PHP 正则表达式中的 ^$ 和 $^ 是不是相同?

Posted

技术标签:

【中文标题】PHP 正则表达式中的 ^$ 和 $^ 是不是相同?【英文标题】:Are ^$ and $^ in PHP regex the same?PHP 正则表达式中的 ^$ 和 $^ 是否相同? 【发布时间】:2011-09-17 10:01:49 【问题描述】:

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

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

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

【问题讨论】:

【参考方案1】:

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

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


您的第二种情况稍微复杂一些,但原理相同。

m 修饰符 (PCRE_MULTILINE) 只是告诉 PCRE 引擎一次性输入整个字符串,而不考虑换行符,但字符串仍然包含“多行”。然后它将^$ 分别视为“行首”和“行尾”。

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

然后这些匹配如下:

    第一个空字符串与起始 $^ 匹配(正如我在上面解释的那样)。

    \n 与您的正则表达式中的相同 \n 匹配。

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

这就是您的第二种情况导致匹配的方式。

【讨论】:

另外有趣的是,我发现这个场景类似于为什么空字符串是其自身的子字符串的问题。所以这根本不是一个愚蠢的问题。事实上,我刚刚投了赞成票!【参考方案2】:

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

^$ 应该匹配一个空字符串,仅此而已。

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

来自PCRE manpages

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

【讨论】:

那么为什么 '/$^\n$/m','\n' 匹配 可能是因为它是您最喜欢的正则表达式引擎中的一个错误:) 或者它可能是这样定义的。但它在逻辑上没有意义,你永远不应该使用它。 @nEAnnam:这对我来说什么都不匹配,也不应该。 @x3ro:那么这是一个 PCRE 错误?因为我验证了问题代码并且$^ does 匹配空字符串(但不是上面的评论)。 也许,因为两者都表示位置,它们在相同的位置匹配,因为我试过 $(space)^ 并且不起作用【参考方案3】:

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

【讨论】:

有一个尺寸......它是0。(对不起,我无法抗拒;) @BoltClock。 :-) 我应该说,there is no spoon。这个例子像黑客帝国一样让我心碎!【参考方案4】:

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

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

/$^/ 不会匹配任何内容,因为从逻辑上讲,字符串的结尾不能在开头之前。

【讨论】:

以上是关于PHP 正则表达式中的 ^$ 和 $^ 是不是相同?的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript与php中的正则表达式是不是一样的?

php 是不是具有解析字符串中的指数的函数(例如:“9.5367431640625e-05”)还是必须通过正则表达式等手动完成?

如何使用 PHP 和正则表达式检查输入值是不是正确? [复制]

PHP/SSH 正则表达式脚本/命令从许多文件中删除相同的恶意软件代码

请问java的正则表达式和php的正则表达式通用吗

PHP 正则函数