如何理解正则表达式'.+?'?其中的.+表示匹配任何字符,而问号?表示非贪婪模式,即只要有一个匹配就停止。因此,这个正则表达式能匹配以下内容:
'cat'
''(即空字符串)
'cat'
''(即空字符串)
"+?" 不是简单的 "+" 量词后面跟着 "?" 量词。而是 "?" 修改 "+" 为执行 "惰性" 或 "非贪婪" 匹配,这意味着匹配最少数量的字符已经足够。
因此,"a+?" 正则表达式只会在 "caaat" 中匹配一个 "a"。
a
在 a
.*?b
中匹配到 a
aba
.*
在 a
.*
?b
中匹配不到任何内容(*
表示零个或多个重复项),由于 .*
被声明为懒惰模式(.*?
),因此会尝试测试正则表达式的其余部分b
在 a.*?
b
中对 a
a
ba
不起作用
.*
的匹配.*
现在匹配到了 a
a
ba
b
在 a.*?
b
中匹配到了 aa
b
a
,我们完成了。因此完整匹配是 aab
a
。
aab
a
。 - Gumboaab
**a
是两个正则表达式的唯一匹配项。 - Gumbo+?(惰性加号)
重复前一个元素一次或多次。这是惰性的,因此引擎首先只匹配前一个元素一次,然后再尝试具有逐渐增加的前一个元素匹配的排列。
/".+?"/
匹配 abc "def" "ghi" jkl 中的 "def"(和 "ghi"),而 /".+"/
则匹配 "def" "ghi"。
您可以在此处找到更多信息。
关于 Perl 如何处理这些量词,有文档可供参考perldoc perlre
。
?
”。请注意,意义不会改变,只是“贪婪性”发生了变化:
*? 匹配 0 次或多次,非贪婪地
+? 匹配 1 次或多次,非贪婪地
?? 匹配 0 次或 1 次,非贪婪地
{n}? 精确匹配 n 次,非贪婪地
{n,}? 至少匹配 n 次,非贪婪地
{n,m}? 至少匹配 n 次但不超过 m 次,非贪婪地
默认情况下,当量化子模式不允许整个模式匹配时,Perl 将回溯。然而,这种行为有时是不可取的。因此,Perl 还提供了“占有”量化器形式。
*+ 匹配 0 次或多次,并且不返回任何内容
++ 匹配 1 次或多次,并且不返回任何内容
?+ 匹配 0 次或 1 次,并且不返回任何内容
{n}+ 精确匹配 n 次,并且不返回任何内容(冗余)
{n,}+ 至少匹配 n 次,并且不返回任何内容
{n,m}+ 至少匹配 n 次但不超过 m 次,并且不返回任何内容
例如,
'aaaa' =~ /a++a/
永远不会匹配,因为 a++
将吞掉字符串中的所有 a
,并且不会留下任何内容供模式的其余部分使用。这个特性非常有用,可以给 Perl 提供关于哪些地方不应该回溯的提示。例如,典型的“匹配双引号字符串”问题可以通过以下方式最有效地执行:
/"(?:[^"\\]++|\\.)*+"/
因为我们知道如果最后一个引号没有匹配成功,回溯是无济于事的。有关更多详细信息,请参见独立子表达式 (?>...)
;占有量化器只是该结构的语法糖。例如,上面的示例也可以写成以下形式:
/"(?>(?:(?>[^"\\]+)|\\.)*)"/
不可避免地,正则表达式将寻找至少一个字符。我已经遇到过空字符串无法通过测试的情况,最好使用.*?
或(.*)?
。有时候你必须在问号前的括号中指定可能为空的字符串部分,这会有所帮助。例如,\d{6}?
会产生错误的结果,而如果我在字符串中说:(\d{6})?
,则会得到正确的结果。
preg_match("/shu\.(\d{6})?/", "shu.321456")
这将产生true
,字符串"shu."
在句点后没有任何int也是如此。