PHP正则表达式中的^ $和$ ^是一样的吗?

时间:2011-06-17 18:21:22

标签: php regex preg-match anchor pcre

为什么这两个正则表达式都成功匹配?

if(preg_match_all('/$^/m',"",$array))
  echo "Match";

if(preg_match_all('/$^\n$/m',"\n",$array))
  echo "Match";

4 个答案:

答案 0 :(得分:11)

$^是零宽度元字符。与其他元字符(例如.一次匹配一个字符(除非与量词一起使用)不同,它们实际上与文字字符不匹配。这就是^$匹配空字符串""的原因,即使正则表达式(无分隔符)包含两个字符,而空字符串包含零。

空字符串不包含任何字符并不重要。它仍然有一个起点和一个终点,因为它是一个空字符串,它们都在同一个位置。因此,无论您使用的^$的顺序或数量如何,其所有排列都应与空字符串匹配。


你的第二个案例稍微复杂一些,但适用相同的原则。

m修饰符(PCRE_MULTILINE)只是告诉PCRE引擎一次性输入整个字符串,无论换行符如何,但字符串仍然包含“多行”。然后,它分别将^$视为“行的开头”和“行的结尾”。

字符串"\n"基本上在逻辑上分为三个部分:"""\n"""(因为换行符被空虚所包围......听起来充满诗意)。

然后这些匹配如下:

  1. 第一个空字符串与起始$^匹配(如上所述)。

  2. \n与正则表达式中的\n匹配。

  3. 第二个空字符串与最后一个$匹配。

  4. 这就是你的第二个案例导致匹配的方式。

答案 1 :(得分:3)

不,不是。实际上,表达式$^永远不应该匹配,因为$表示字符串的结尾,而^表示开头。但正如我们所知,结尾不能在字符串开头之前出现:)

^$应匹配一个空字符串,并且只匹配。

  

“行首”元字符(^)仅匹配字符串的开头,而“行尾”元字符($)仅匹配字符串的末尾,[...]

来自PCRE manpages

请注意,通过添加PCRE_MULTILINE修饰符,$变为EOL且^变为BOL,它将匹配(感谢netcoder指出它)。不过,我个人不会使用它。

答案 2 :(得分:1)

Regex.IsMatch ("", "$^")也在C#中匹配。由于它是一个空字符串,因此没有大小。在索引-1处,它同时位于字符串的结尾和开头。好问题!

答案 3 :(得分:0)

在正则表达式中,^匹配字符串的开头,$匹配字符串的结尾。

因此,正则表达式/^$/将成功匹配一个完全空的字符串(没有别的)。

/$^/将无法匹配任何内容,因为逻辑上你不能在字符串开头之前得到字符串的结尾。