【问题标题】:Preg match if not [duplicate]如果不是,则预匹配[重复]
【发布时间】:2011-09-09 09:37:07
【问题描述】:

是否可以对不应该匹配但仍返回 true 的内容执行 preg_match()

例如,目前我们有...

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

我们要检查 Mozilla 字符串是否不在 $agent 中,但仍有 preg_match 返回 true。

我们无法将其更改为:

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

【问题讨论】:

  • 我不明白。为什么不能使用后者?
  • 正则表达式部分是动态的,我们可以改变它,但我们不能改变它的行,虽然它只是为了演示
  • 但这没关系。即使你的模式不是固定的,你想检查模式是否不匹配,你只需要将preg_match的返回值取反即可。
  • 关键是我不能改变脚本的逻辑,如果可以的话我就用if (!preg_match
  • 副本不好。 preg_match() 是一个难以解决的函数。这不是关于正则表达式,而是关于 preg_match 的奇怪返回值(多种可能的 types - 布尔值和整数)。

标签: php regex preg-match


【解决方案1】:

你想要的是negative lookahead,语法是:

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

实际上,您可能只需要 #^(?!Mozilla)# 就可以了。我不知道 PHP 会如何看待这种仅是零宽度标记但 I've tested it in JavaScript and it works fine 的模式。


编辑:

如果您想确保Mozilla 不会出现在字符串中任何地方,您可以使用这个...

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

...但前提是你不能使用它!

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

【讨论】:

    【解决方案2】:
    if (preg_match('#^Mozilla(.*)#', $agent) === 0) {
    

    希望我没有误解你的问题。 preg_match 将返回 0(未找到)、1(找到 1 个匹配项,不搜索更多)或 false(发生一些问题)。当falsepreg_match 返回时,我使用=== 不返回true。

    【讨论】:

    • preg_match('#^Mozilla(.*)#', $agent) === 0!preg_match('#^Mozilla(.*)#', $agent) 相同,提问者表示他们不能这样做。
    • @walf 重点不一样。 0 == false 但 0 !== false。
    • 没有人讨论正则表达式中的语法错误,我敢打赌$agent 将永远是一个字符串。因此preg_match()永远返回false!preg_match()preg_match() === 0产生完全相同布尔值。无论哪种方式,您都没有读到正则表达式是动态的,因此实际代码类似于if (preg_match($test, $agent)) {,并且您不能(通常)选择是否动态否定preg_match()
    • 是的,PHP 文档很神秘。 !== false!== 0 之间存在差异。 !== 0!== 1 应用于检查字符串是否匹配(或不匹配)某些正则表达式(不是 !== false!== true
    【解决方案3】:

    您可以像这样使用负前瞻:

    #^(?!Mozilla)(.*)#
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-18
      • 1970-01-01
      • 2018-02-07
      • 1970-01-01
      • 1970-01-01
      • 2015-04-12
      • 1970-01-01
      相关资源
      最近更新 更多