2012-06-26 58 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”尝试并成功。