为什么这两个正则表达式都成功匹配?
if(preg_match_all('/$^/m',"",$array))
echo "Match";
if(preg_match_all('/$^\n$/m',"\n",$array))
echo "Match";
答案 0 :(得分:11)
$
和^
是零宽度元字符。与其他元字符(例如.
一次匹配一个字符(除非与量词一起使用)不同,它们实际上与文字字符不匹配。这就是^$
匹配空字符串""
的原因,即使正则表达式(无分隔符)包含两个字符,而空字符串包含零。
空字符串不包含任何字符并不重要。它仍然有一个起点和一个终点,因为它是一个空字符串,它们都在同一个位置。因此,无论您使用的^
和$
的顺序或数量如何,其所有排列都应与空字符串匹配。
你的第二个案例稍微复杂一些,但适用相同的原则。
m
修饰符(PCRE_MULTILINE
)只是告诉PCRE引擎一次性输入整个字符串,无论换行符如何,但字符串仍然包含“多行”。然后,它分别将^
和$
视为“行的开头”和“行的结尾”。
字符串"\n"
基本上在逻辑上分为三个部分:""
,"\n"
和""
(因为换行符被空虚所包围......听起来充满诗意)。
然后这些匹配如下:
第一个空字符串与起始$^
匹配(如上所述)。
\n
与正则表达式中的\n
匹配。
第二个空字符串与最后一个$
匹配。
这就是你的第二个案例导致匹配的方式。
答案 1 :(得分:3)
不,不是。实际上,表达式$^
永远不应该匹配,因为$
表示字符串的结尾,而^
表示开头。但正如我们所知,结尾不能在字符串开头之前出现:)
^$
应匹配一个空字符串,并且只匹配。
“行首”元字符(^)仅匹配字符串的开头,而“行尾”元字符($)仅匹配字符串的末尾,[...]
请注意,通过添加PCRE_MULTILINE
修饰符,$
变为EOL且^
变为BOL,它将匹配(感谢netcoder指出它)。不过,我个人不会使用它。
答案 2 :(得分:1)
Regex.IsMatch ("", "$^")
也在C#中匹配。由于它是一个空字符串,因此没有大小。在索引-1处,它同时位于字符串的结尾和开头。好问题!
答案 3 :(得分:0)
在正则表达式中,^
匹配字符串的开头,$
匹配字符串的结尾。
因此,正则表达式/^$/
将成功匹配一个完全空的字符串(没有别的)。
/$^/
将无法匹配任何内容,因为逻辑上你不能在字符串开头之前得到字符串的结尾。