这些perl兼容的正则表达式之间有什么区别?

时间:2009-08-17 14:49:12

标签: php regex

another question的答案激起了我的好奇心。

考虑:

$string = "asfasdfasdfasdfasdf[[sometextomatch]]asfkjasdfjaskldfj";

$regex = "/\[\[(.+?)\]\]/";
preg_match($regex, $string, $matches);

$regex = "/\[\[(.*)\]\]/"; 
preg_match($regex, $string, $matches);

我问两个正则表达式之间有什么区别。我得到的aswer是“。*”匹配任何字符的次数是0次或更多次, 和“。+?”匹配任何字符的次数尽可能少1次或多次。

我以不同的方式阅读这些正则表达式,所以我自己做了一些实验,但没有得出任何结论。 Php.net说“?”相当于{0,1}所以你可以重写

"/\[\[(.+?)\]\]/"

作为

"/\[\[((.+){0,1})\]\]/"

"/\[\[(.{0,})\]\]/"

"/\[\[(.*)\]\]/"

他们会捕捉不同的文字吗?一个更便宜的区别是什么?我是肛门吗?

5 个答案:

答案 0 :(得分:3)

独立,?确实意味着{0,1},但是,当它出现*+?或{{1}之类的内容时(例如),{3,6}完全意味着其他东西,即它做最小匹配。所以,不,你不能将?重写为/\[\[(.+?)\]\]/。 : - )

答案 1 :(得分:2)

举一个例子,你会得到不同的结果:

foo [[bar]] baz [[quux]]

您的第一个正则表达式将匹配[[bar]][[quux]],而第二个正则表达式仅匹配[[bar]] baz [[quux]]

原因是懒惰的quantifier(后缀为?)将匹配正常贪婪模式与可能重复的最大值匹配的最小可能重复次数:

  

但是,如果量词后跟一个问号,那么它就不再是贪婪的,而是匹配可能的最小次数,因此模式/\*.*?\*/使用C注释做正确的事。各种量词的含义不会改变,只是匹配的首选数量。不要混淆这种问号的使用与其本身作为量词的用途。因为它有两个用途,它有时会出现加倍,如\d??\d按优先级匹配一个数字,但如果这是模式其余部分匹配的唯一方式,则可以匹配两个。

答案 2 :(得分:2)

通常,?表示“捕获前面的事物0或1次”。但是,在*+之后使用时,?会修改*+的含义。通常,* / +表示“匹配0(1表示+)或更多次,并尽可能多地匹配”。添加?会将该含义修改为“匹配0(1代表+)或更多次,但匹配尽可能少”。默认情况下,这些表达式是“贪婪的”,?将它们修改为非贪婪。

答案 3 :(得分:0)

?只会捕获一次((0,1)表示0到1次),因为*将捕获它在字符串中出现的次数。< / p>

来自this page:

  

如果您使用<.+>并在The <em>Big</em> Dog.上使用它,则会<em>Big</em><.+?>仅匹配<em>

的位置

答案 4 :(得分:0)

/.*/   ===  /.{0,}/
/.+/   ===  /.{1,}/
/.?/   ===  /.{0,1}/

"aaaaaa" =~ /a*/;  # "aaaaaa"
"aaaaaa" =~ /a*?/; # ""