首页 > 解决方案 > 用正则表达式找到相反的

问题描述

我有这段代码,效果很好

$match = false;
$string = 'The thing is S25697 and blue';
$reg_exp = '^The thing is.*(S\d).*(blue|red)';
$match = @preg_match("/$reg_exp/iu", $string);
if ($match) echo "found";
else echo "not found";

这个正则表达式给了我以下结果

$string = 'The thing is S25697 and blue'; #<--$match = true
$string = 'The thing is S2w697 and green'; #<--$match = false
$string = 'The thing is S2e697 and yellow'; #<--$match = false
$string = 'The thing is S2b697 and pink'; #<--$match = false
$string = 'The thing is S256b7 and red'; #<--$match = true

现在我想调整正则表达式以获得蓝色或红色的相反值。但 PHP 代码本身不得更改。这是我想要得到的一个例子:

$string = 'The thing is S25697 and blue'; #<--$match = false
$string = 'The thing is S2w697 and green'; #<--$match = true
$string = 'The thing is S2e697 and yellow'; #<--$match = true
$string = 'The thing is S2b697 and pink'; #<--$match = true
$string = 'The thing is S256b7 and red'; #<--$match = false

我发现除了指定的字符串和其他答案之外的所有内容都匹配。但此时没有人工作。我试过这个

$match = false;
$string = 'The thing is S25697 and blue';
$reg_exp = '^The thing is.*(S\d).*(?!.*(?:blue|red))';
$match = @preg_match("/$reg_exp/iu", $string);
if ($match) echo "found";
else echo "not found";

但结果是“找到”

标签: phpregex

解决方案


Use

^The thing is.*\b(S\d)(?!.*\b(?:blue|red)\b)

See proof

EXPLANATION

                         EXPLANATION
--------------------------------------------------------------------------------
  ^                        the beginning of the string
--------------------------------------------------------------------------------
  The thing is             'The thing is'
--------------------------------------------------------------------------------
  .*                       any character except \n (0 or more times
                           (matching the most amount possible))
--------------------------------------------------------------------------------
  \b                       the boundary between a word char (\w) and
                           something that is not a word char
--------------------------------------------------------------------------------
  (                        group and capture to \1:
--------------------------------------------------------------------------------
    S                        'S'
--------------------------------------------------------------------------------
    \d                       digits (0-9)
--------------------------------------------------------------------------------
  )                        end of \1
--------------------------------------------------------------------------------
  (?!                      look ahead to see if there is not:
--------------------------------------------------------------------------------
    .*                       any character except \n (0 or more times
                             (matching the most amount possible))
--------------------------------------------------------------------------------
    \b                       the boundary between a word char (\w)
                             and something that is not a word char
--------------------------------------------------------------------------------
    (?:                      group, but do not capture:
--------------------------------------------------------------------------------
      blue                     'blue'
--------------------------------------------------------------------------------
     |                        OR
--------------------------------------------------------------------------------
      red                      'red'
--------------------------------------------------------------------------------
    )                        end of grouping
--------------------------------------------------------------------------------
    \b                       the boundary between a word char (\w)
                             and something that is not a word char
--------------------------------------------------------------------------------
  )                        end of look-ahead

推荐阅读