Hows做正则表达式:/。+?/工作?

时间:2009-08-17 11:51:10

标签: regex

'。+?'怎么样?正规表达工作? 。+部分是否匹配任何内容,以及?部分说它可以在那里吗?因此,例如,此正则表达式将匹配:

'猫'
''(即没有写任何东西,只是空字符串)

5 个答案:

答案 0 :(得分:10)

“+?”不是“+”量词后跟“?”量词。取而代之的是“?”修改“+”以执行“懒惰”或“非贪婪”匹配,这意味着匹配的字符数最少已足够。

那么“a +?”正则表达式只匹配“caaat”中的单个“a”。

答案 1 :(得分:8)

除了汉斯·凯斯汀已经说过的话,一个懒惰乘法器将完成正常贪心乘数的精确对数:可能的匹配保持尽可能小,并测试正则表达式的其余部分。

因此,如果您使用字符串aaba并在其上测试正则表达式a.*b,则内部处理步骤如下:

    a a匹配 .*b a {{1} } aba .* a中的
  1. .* 匹配b {{1 }} a,因为a贪婪
    1. ba 然后匹配.* .* a
    2. ab 然后匹配a .*
  2. a aba 中的
  3. b 失败,因为没有留下任何信件
    • 回溯向前退一步,a.*现在只会与b .* bb
    • 中的a匹配
  4. ab a 中的
  5. b 仍然在a.* b < /强>
    • 回溯向后退一步,aab现在只与a .* b
    • 中的a匹配
  6. a ba 中的
  7. b 现在与a.* {中的b匹配{1}} b我们已经完成了。
  8. 完整匹配为 aa b

    如果我们对惰性乘数(a)执行相同操作,则处理将执行oposite,尝试尽可能匹配尽可能少的字符:

      aab a匹配 a.*?b a {{1} } a .*?b a中的
    1. aba 与任何内容都不匹配(.* =零或更多重复),并且因为a被声明为惰性(.*),所以正则表达式的其余部分被测试
    2. ?b * 中的
    3. .* .*? b上失败 a.*?
      • 回溯会尝试增加b
      • 的匹配
    4. a 现在匹配a ba .*
    5. .* a 匹配a ba b我们已经完成了。

      如果 a.*? b完全匹配。

答案 2 :(得分:4)

<强> +? (懒惰加)

  

重复上一个项目或   更多。懒,所以引擎第一   仅匹配上一个项目一次,   在尝试与永远的排列之前   增加前面的匹配   项目

/".+?"/ abc“def”“ghi”jkl 中匹配“def”(和“ghi”),而/".+"/匹配“def”“ghi”

您可以找到更多信息here

答案 3 :(得分:1)

有关于Perl如何处理这些量词perldoc perlre的文档。

默认情况下,量化的子模式是“贪婪的”,也就是说,它将尽可能多地匹配(给定一个特定的起始位置),同时仍然允许模式的其余部分匹配。如果您希望它与可能的最小次数匹配,请使用“?”跟随量词。请注意,含义不会改变,只是“贪婪”:
    *?     Match 0 or more times, not greedily
    +?     Match 1 or more times, not greedily
    ??     Match 0 or 1 time, not greedily
    {n}?   Match exactly n times, not greedily
    {n,}?  Match at least n times, not greedily
    {n,m}? Match at least n but not more than m times, not greedily
默认情况下,当量化的子模式不允许整个模式的其余部分匹配时,Perl将回溯。但是,这种行为有时是不可取的。因此,Perl也提供了“占有”量词形式。
    *+     Match 0 or more times and give nothing back
    ++     Match 1 or more times and give nothing back
    ?+     Match 0 or 1 time and give nothing back
    {n}+   Match exactly n times and give nothing back (redundant)
    {n,}+  Match at least n times and give nothing back
    {n,m}+ Match at least n but not more than m times and give nothing back
例如,
   'aaaa' =~ /a++a/
永远不会匹配,因为a++将吞噬字符串中的所有a,并且不会为模式的剩余部分留下任何内容。此功能对于提供有关不应回溯的位置的perl提示非常有用。例如,当写为:时,可以最有效地执行典型的“匹配双引号字符串”问题:
   /"(?:[^"\\]++|\\.)*+"/
我们知道,如果最终报价不匹配,回溯将无济于事。有关详细信息,请参阅独立子表达式(?>...);占有量词只是该构造的语法糖。例如,上面的例子也可以写成如下:
   /"(?>(?:(?>[^"\\]+)|\\.)*)"/

link

答案 4 :(得分:0)

不可避免地,正则表达式将寻找至少一个字符。我遇到过一个空字符串不能通过该测试的情况,最好使用.*?(.*)?代替,有时你必须指定字符串的一部分可能是在问号之前的大括号中为null,这会有所帮助。例如。 \d{6}?会产生错误的结果,而如果我在字符串中说过(\d{6})?则说:

preg_match("/shu\.(\d{6})?/", "shu.321456")

这将产生true,因此字符串"shu."在句点之后没有任何int