2012-06-26 92 views
0

我正在閱讀Jeffrey Friedl的書Mastering Regular Expressions 3rd Ed。在274頁,Jeffrey要求他的讀者調查爲什麼正則表達式匹配字符串(用粗體標記的匹配字符)「year = days /x divide x // 365;/x假設非閏年x/「。結束回溯步驟x/

我從正則表達式中刪除了結尾x/。所以正則表達式的輸出是「/ x dividex∥365;」。但是在我加回x/之後,正則表達式的輸出爲「/ x除x // 365;/x假設非正態分佈,閏年x /「

有人可以告訴我Perl的正則表達式引擎的回溯步驟結束x/

這是我的這個問題的Perl腳本。

my $str = "years = days /x divide x//365; /x assume non-leap year x/"; 
if ($str =~ m{(/x([^/]|[^x]/)*)}) { 
    print "\$1: '$1'\n"; # output: $1: '/x divide x//365; ' 
} else { 
    print "not matched.\n"; 
} 


$str = "years = days /x divide x//365; /x assume non-leap year x/"; 
if ($str =~ m{(/x([^/]|[^x]/)*x/)}) { 
    print "\$1: '$1'\n"; # output: $1: '/x divide x//365; /x assume non-leap year x/' 
} else { 
    print "not matched.\n"; 
} 

回答

2

這裏的破敗:

/X - 匹配/後跟一個x
([^ /] | [^ X] /)* - 匹配任何不是/或不是一個X後跟斜槓 - 多次儘可能
X/ - 匹配的x接着是/

所以基本上它說:從/x開始,然後匹配除x/之外的所有內容,並以x/結束。

+0

但匹配的字符串包含幾個斜線(/)。那麼爲什麼? – Cylian

+0

當正則表達式引擎遇到'/'時,它將進入下一個選擇:匹配一個非x字符後跟一個'/'(例如「//」或「/」)。這將匹配所有的東西,直到它不能滿足其中一個選項,並且會關閉'x /'。 –

+0

我從正則表達式中刪除了結尾「x /」。所以正則表達式的輸出**「/ x([^ /] | [^ x] /)*」**是**「/ x divide x // 365;」**。但是在我添加「x /」之後,正則表達式**「/ x([^ /] | [^ x] /)* x /」**的輸出是**「/ x divide x // 365;/x假設非閏年x/**。你能告訴我正則表達式引擎的回溯步驟嗎? –

0

我明白了。約瑟夫是對的。當第二個「/ x」匹配失敗時,正則表達式引擎回溯到「/ x」嘗試併成功。