Ruby 1.9正则表达式Lookbehind Assertion&Anchors

问题描述:

Ruby 1.9正则表达式支持lookbehind断言,但在模式中传递锚时似乎很困难。当锚点在前瞻断言中传递时,它运行得很好。Ruby 1.9正则表达式Lookbehind Assertion&Anchors

"well substring! "[/(?<=^|\A|\s|\b)substring!(?=$|\Z|\s|\b)/] #=> RegexpError: invalid pattern in look-behind: /(?<=^|\A|\s|\b)substring(?=$|\Z|\s|\b)/ 

有没有人知道如何使锚在lookbehead断言中工作?

是否有一个特殊的转义序列或分组是后视所需的?

我已经在1.9.1-p243,p376和1.9.2-preview3中测试了这种行为,以防万一它被修补。

+0

最终,这并不像锚点\ b不被识别为像前视断言那样的字边界,而是一个锚问题。使用不是一个不是字的边界 - [^ \ B]解决了这个问题。 – klappy 2010-08-02 20:43:56

+0

这可能会让你感到惊讶,但是如果'\ b'在你身后,它也就在你的面前!至少在Java中,所有零宽度锚都是如此。 – polygenelubricants 2010-08-03 07:02:23

+0

Klappy!这是一个很小的世界! – tybro0103 2011-09-30 02:53:13

看起来像后视范围的解释是范围[]而不是像预测断言的组()。这可能意味着\ b是一个无效的退格字符而不是一个字边界。

"well substring! "[/(?<=^|\A|\s|[^\B])substring!(?=$|\Z|\s|\b)/] #=> substring! 
"well substring! "[/(?<=^|\A|\s|[^\B])substring(?=$|\Z|\s|\b)/] #=> substring 
"well !substring! "[/(?<=^|\A|\s|[^\B])substring(?=$|\Z|\s|\b)/] #=> substring 
"well !substring! "[/(?<=^|\A|\s|[^\B])!substring(?=$|\Z|\s|\b)/] #=> !substring 

当所有其他的失败...使用双重否定!

看起来你是对的:\b按照预期的方式在向前看,但在向后看来,它被视为语法错误。

在这种情况下它并不重要:如果(?<=^|\A|\s|\b)会产生所需的结果,则无论如何您都需要\b。断言后面的字符必须是s - 一个字符 - 所以\b表示(1)前一个字符是而不是一个字符,或者(2)有没有以前的字符。情况如此,^\A\s都是多余的。

但是,如果字符串以!开头,这是一个不同的故事。 ^\A仍然匹配字符串的开头,之前!,但\b匹配它。如果你想匹配!substring!作为一个完整的字符串,你必须使用/\A!substring!\Z/,但如果你只想匹配整个词substring你必须使用/\bsubstring\b/

至于[^\B],只是匹配除B以外的任何字符。像\b,\B是一个零宽度断言,并且一个字符类只能匹配一个字符。一些正则表达式会为无效转义序列\B抛出异常,但是Ruby(或者更可能是Oniguruma)会让它滑动。

是的,看起来像Ruby 1.9.2 dosent支持\ b的背后。

ruby-1.9.2-p180 :034 > "See Jeffs book and it seems fine!".gsub(/(?=s\b)(?<=\bJeff)/,"'") 
SyntaxError: (irb):34: invalid pattern in look-behind: /(?=s\b)(?<=\bJeff)/ 
from /home/pratikk/.rvm/rubies/ruby-1.9.2-p136/bin/irb:16:in `<main>' 

ruby-1.9.2-p180 :033 > "See Jeffs book and it seems fine!".gsub(/(?=s\b)(?<=Jeff)/,"'") 
=> "See Jeff's book and it seems fine!" 
+0

它确实支持\ d。 'ruby-1.9.2-p180:002>“298281974382”.gsub(/(?=(\ d \ d \ d)+ $)“298,281,974,382”' – 2011-03-17 20:31:01

+0

这是因为\ d只是像[0-9]这样的字符类。这是有道理的,你可以在lookbehind anchor中包含字符类,但是可能没有多少意义(或者可能解释)将一个类似于\ b的锚放置在一个锚点中。 – 2013-02-27 00:42:35