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 正则表达式中的 ^$ 和 $^ 是不是相同?的主要内容,如果未能解决你的问题,请参考以下文章
php 是不是具有解析字符串中的指数的函数(例如:“9.5367431640625e-05”)还是必须通过正则表达式等手动完成?
如何使用 PHP 和正则表达式检查输入值是不是正确? [复制]