Ruby 1.9正则表达式支持lookbehind断言,但在模式中传递锚点时似乎有困难。当在前瞻断言中传递锚点时,它运行得很好。
"well substring! "[/(?<=^|\A|\s|\b)substring!(?=$|\Z|\s|\b)/] #=> RegexpError: invalid pattern in look-behind: /(?<=^|\A|\s|\b)substring(?=$|\Z|\s|\b)/
是否有人知道如何使锚点在后视断言中起作用,就像在前瞻中一样?
是否存在lookbehind所需的特殊转义序列或分组?
我已经在1.9.1-p243,p376和1.9.2-preview3中测试了这种行为,以防它被修补。
答案 0 :(得分:1)
看起来你是对的:\b
在预测中按预期工作,但在后视中它被视为语法错误。
在这种情况下并不重要:如果(?<=^|\A|\s|\b)
会产生所需的结果,那么无论如何都需要\b
。断言后的字符必须是s
- 一个单词字符 - 所以\b
表示(1)前一个字符不一个单词字符,或者(2) ) 没有前一个字符。在这种情况下,^
,\A
和\s
都是多余的。
但是,如果字符串以 至于!
开头,那就是另一个故事。 ^
和\A
仍然匹配字符串的开头,之前 !
,但\b
匹配之后的 。如果您想将!substring!
与完整字符串匹配,则必须使用/\A!substring!\Z/
,但如果您只想匹配整个字substring
,则必须使用/\bsubstring\b/
。< / p>
[^\B]
,它只匹配除B
之外的任何字符。与\b
类似,\B
是零宽度断言,字符类必须恰好匹配一个字符。一些正则表达式的味道会为无效的转义序列\B
抛出异常,但Ruby(或Oniguruma,更有可能)会让它滑动。
答案 1 :(得分:0)
看起来,lookbehind的解释是范围[]的解释,而不是像前瞻断言那样的group()。这可能意味着\ 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
当其他所有方法都失败时......使用双重否定!
答案 2 :(得分:0)
是的,看起来像Ruby 1.9.2不支持\ 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!"