正则表达式中的双重EOL

时间:2013-10-05 07:16:21

标签: ruby regex

我需要在字符串中的双EOL之后插入一些额外的文本。我遇到了奇怪的行为:当我在双EOL之后对符号的出现表示肯定时,所有人都在几乎罚款:

"A\n\nA".gsub /(^{2})(?=A)/, '♻'
# ⇒ "♻A\n\n♻A"

\A(字符串的开头)有一个奇怪的匹配,但现在对我来说没关系。当我尝试否定前瞻时会出现真正的问题:

"A\n\nA".gsub /(^{2})(?!B)/, '♻'
# ⇒ "♻A\n♻\n♻A"
# WHAT?  ⇑

请你解释一下我在regexx中误解的原因,为什么中间匹配发生?我应该如何用我需要的替代双EOL。

UPD 中间匹配发生是因为^是元字符,匹配no-thing,谢谢@bsd。但是,替换双EOL的正确方法是什么?我可能会坚持下去。

提前致谢。

1 个答案:

答案 0 :(得分:2)

我认为你认为^可以贪婪匹配是错误的。 ^匹配行的开头。

^也是一个元字符,它匹配字符之间的零宽度位置。连续的换行符/起始字符之间有多少个零宽度位置?它可能会在每个角色之前匹配。

看看这个

"A\n\nA".scan /(^{2})(?!C)/
=> [[""], [""], [""]]

你可能意味着

"A\n\nA".gsub /([\n]{2})(?!C)/ , "\\1♻'"
=> "A\n\n♻A"

编辑:

所以如果你想要它跨所有平台。你可以把它写成:

"A\r\n\r\nA".gsub /((?:\r?\n){2})(?!C)/ , "\\1♻"
=> "A\r\n\r\n♻A"

"A\n\n\n\nA".gsub /((?:\r?\n){2})(?!C)/ , "\\1♻"
=> "A\n\n♻\n\n♻A"

EDIT2: @Alan Moore说,在Ruby 2.0中,你可以将上面的正则表达式简化为

"A\n\n\n\nA".gsub /(\R{2})(?!C)/ , "\\1♻"