Preg匹配不成功怎么办?

10

能否在不匹配的情况下仍返回true,对于不应该匹配的内容进行preg_match()操作是否可行?

例如,目前我们有...

if (preg_match('#^Mozilla(.*)#', $agent)) {

我们希望检查$agent中是否没有Mozilla字符串,但仍然让preg_match返回true。

我们不能将其更改为:

if (!preg_match('#^Mozilla(.*)#', $agent)) {

4
我不明白。为什么你不能使用后者? - Gumbo
1
正则表达式部分是动态的,我们可以更改它,但不能更改它所经过的行,这只是为了演示。 - fire
1
但这并不重要。即使您的模式不是固定的,并且想要检查模式是否不匹配,您只需要反转 preg_match 返回值即可。 - Gumbo
1
重点是我不能改变脚本的逻辑,如果可以的话,我就会直接使用 if (!preg_match - fire
重复的不是好的。preg_match() 是一个难以掌握的函数。这不是关于正则表达式,而是关于 preg_match 的奇怪返回值(多种可能的 类型 - 布尔值和整数)。 - Peter Mortensen
这段内容应该不会被删除。kapa的回答是非常重要的见解。否则,全球范围内的抓狂现象将会大幅增加。 - Peter Mortensen
3个回答

14

你需要的是一个负向先行断言,其语法为:

if (preg_match('#^(?!Mozilla).#', $agent)) {

实际上,你可以只使用 #^(?!Mozilla)# 来完成这个任务。我不确定 PHP 对于一个什么都没有的零宽度模式会有什么感觉,但是我已经在 JavaScript 中测试过了,它可以正常工作。


编辑:

如果你想确保字符串中任何地方都没有出现 Mozilla,可以使用以下代码...

if (preg_match('#^((?!Mozilla).)*$#', $agent)) {

...但仅在无法使用此选项时才这样做!

if (strpos($agent, 'Mozilla') !== false) {

3
if (preg_match('#^Mozilla(.*)#', $agent) === 0) {

我希望我没有误解你的问题。 preg_match 要么返回 0(未找到),要么返回 1(找到一个匹配项,不会继续搜索),要么返回 false(发生了一些问题)。 我使用 === 来避免在从 preg_match 返回 false 时返回 true。

preg_match('#^Mozilla(.*)#', $agent) === 0!preg_match('#^Mozilla(.*)#', $agent) 是相同的,提问者表示他们无法使用后者。 - Walf
@walf 这不是同一回事,这才是要点。0 == false 但是0 !== false。 - kapa
没有人讨论正则表达式中的语法错误,我敢打赌$agent将始终是一个字符串。因此,preg_match()永远不会返回false,而!preg_match()preg_match() === 0产生完全相同的布尔值。无论哪种方式,你都没有读到正则表达式是动态的,所以实际代码将像这样:if (preg_match($test, $agent)) {,并且你不能(轻松地)选择是否动态否定preg_match() - Walf
是的,PHP文档确实有些晦涩难懂。!== false!== 0之间存在差异。应该使用!== 0!== 1来检查字符串是否匹配(或不匹配)某个正则表达式(而不是使用!== false!== true)。 - Peter Mortensen

2
您可以像这样使用负向先行断言:
#^(?!Mozilla)(.*)#

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接