我需要在字符串中的双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的正确方法是什么?我可能会坚持下去。
提前致谢。
答案 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♻"