2010-08-02 52 views
1

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

回答

0

看起來像後視範圍的解釋是範圍[]而不是像預測斷言的組()。這可能意味着\ 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 

當所有其他的失敗...使用雙重否定!

1

看起來你是對的:\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)會讓它滑動。

0

是的,看起來像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)+ $)<= \ d)/,「,」) =>「298,281,974,382」' – 2011-03-17 20:31:01

+0

這是因爲\ d只是像[0-9]這樣的字符類。這是有道理的,你可以在lookbehind anchor中包含字符類,但是可能沒有多少意義(或者可能解釋)將一個類似於\ b的錨放置在一個錨點中。 – 2013-02-27 00:42:35

相關問題