PHP反向预匹配

PHP反向预匹配,php,regex,if-statement,preg-match,reverse,Php,Regex,If Statement,Preg Match,Reverse,此代码过滤变量以决定是否显示它。$filter的一个示例条目是“office”或“164(.*)976” 我想知道是否有一种简单的方式来表示:$filter在$node中不匹配。以正则表达式的形式 所以。。。不是“if(!preg_match”,而是更多的$filter=“!office”或“!164(.*)976”,而是一个有效的?如果您确实想使用“负正则表达式”而不是简单地反转正正则表达式的结果,可以这样做: if(preg_match("/" . $filter . "/i", $node

此代码过滤变量以决定是否显示它。$filter的一个示例条目是“office”或“164(.*)976”

我想知道是否有一种简单的方式来表示:$filter在$node中不匹配。以正则表达式的形式


所以。。。不是“if(!preg_match”,而是更多的$filter=“!office”或“!164(.*)976”,而是一个有效的?

如果您确实想使用“负正则表达式”而不是简单地反转正正则表达式的结果,可以这样做:

if(preg_match("/" . $filter . "/i", $node)) {
    echo $node;
}
如果在
$filter
中不包含正则表达式/子字符串,则将匹配字符串

说明:(以
office
为例)

(?!…)
就是您要找的

要排除主题中任何位置出现的特定字符串,可以使用此双重断言方法:

^          # Anchor the match at the start of the string
(?:        # Try to match the following:
 (?!       # (unless it's possible to match
  office   # the text "office" at this point)
 )         # (end of negative lookahead),
 .         # Any character
)*         # zero or more times
$          # until the end of the string

它仍然允许指定任意(……)主正则表达式。但如果您只想禁止字符串,则可以省略该选项。

mario的答案2是正确的答案,原因如下:

首先回答Justin Morgan的评论


我很好奇,你知道这会有什么表现吗 与!preg_match()方法相反?我不是在 我可以同时测试它们。-贾斯汀·摩根2011年4月19日21:53

考虑一下门逻辑

何时否定preg_match():当查找匹配项时,您希望条件为1)如果缺少所需的正则表达式,则为true;如果存在正则表达式,则为false

何时对正则表达式使用否定断言:在查找匹配项时,如果字符串仅与正则表达式匹配,则希望条件为true,如果找到其他内容,则条件为false。如果您确实需要在允许删除允许的字符的同时测试不需要的字符,那么这是必要的

如果存在正则表达式,则仅对(preg_match()==1)的结果求反进行测试。如果需要“bar”,并且不允许使用数字,则以下操作将不起作用:

preg_match('/(?=^((?!not_this).)+$)  (......)/xs', $string);
因此,为了真正测试多个正则表达式,初学者将使用多个preg_match()调用进行测试。。。我们知道这是一种非常业余的方式

因此,Op希望测试一个字符串是否有可能的正则表达式,但只有当该字符串至少包含其中一个正则表达式时,该条件才能作为true传递。对于大多数简单的情况,简单地否定preg_match()就足够了,但对于更复杂或更广泛的正则表达式模式就不行了。我将用我的情况来描述一个更真实的场景:

假设您想为一个人的名字,特别是姓氏创建一个用户表单。您希望系统接受所有字母,无论大小写和位置如何,接受连字符,接受撇号,并排除所有其他字符。我们知道为所有不需要的字符匹配正则表达式是我们想到的第一件事,但是假设您支持UTF-8。。。那是很多角色!您的程序将几乎与UTF-8表一样大,仅在一行上!我不在乎你有什么硬件,你的服务器应用程序对一个命令的长度有一个有限的限制,更不用说200个带括号的子模式的限制了,所以整个UTF-8字符表(减去[a-Z]、[a-Z]、-)太长了,更不用说程序本身会很庞大了

由于我们不会在字符串上使用if(!preg_match('.\\$\%.。#\\\$\%..这可能会很长,也不可能进行计算…以查看字符串是否不好,因此我们应该使用更简单的方法测试,在正则表达式上使用断言否定查找,然后使用以下方法否定整个结果:

if (preg_match('bar', 'foo2bar') === 1) {
  echo "found 'bar'"; // but a number is here, so fail.
}

if (!pregmatch('[0-9]', 'foobar') === 1) {
  echo "no numbers found"; // but didn't test for 'bar', so fail.
}

你能告诉我为什么不使用
!preg_match()
?我很好奇,你知道这与
!preg_match()相比会有什么性能吗
方法?我不是在一个可以同时测试这两种方法的地方。我希望此解决方案总体上比否定方法慢,因为环顾断言会增加开销。实际结果将取决于您的输入是否通常匹配
$filter
(在这种情况下,否定会更快)或是否匹配(在这种情况下,这种方法可能会更快)。非常感谢您提供的否定断言链接,这有力地解决了我的问题,标记的答案也很好,但我非常喜欢页面中的详细信息。thx到目前为止。
if (preg_match('bar', 'foo2bar') === 1) {
  echo "found 'bar'"; // but a number is here, so fail.
}

if (!pregmatch('[0-9]', 'foobar') === 1) {
  echo "no numbers found"; // but didn't test for 'bar', so fail.
}
<?php
  $string = "O'Reilly-Finlay";
  if (preg_match('/?![a-z\'-]/i', $string) === 0) {
    echo "the given string matched exclusively for regex pattern";
    // should not work on error, since preg_match returns false, which is not an int (we tested for identity, not equality)
  } else {
    echo "the given string did not match exclusively to the regex pattern";
  }
?>