1

I have this code which works very well

$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";

This regex gives me the following results

$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

Now I want to adjust the regex to get the opposite of blue or red. But the PHP code itself shall not be changed. Here is an example what I want to get as a result:

$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

I have found this Match everything except for specified strings and other answers. But no one work at this moment. I have try this

$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";

But the result is "found"

  • What's wrong with if NOT match `if (!$match)` ? – AbraCadaver Aug 18 '20 at 17:24
  • What are you trying to accomplish? Extract `S\d` from the string and match the color at the end? So are you trying to retrieve `S2w697` and `green`? Or just get the whole string? It's unclear. In any case, you can just append `(*SKIP)(*FAIL)|.+` to the end of your regex to get whatever doesn't match your current pattern. – ctwheels Aug 18 '20 at 17:26
  • The if $ match is fixed in the code. This cannot be changed. I have a file with 1000 entries. From this I search for all entries as in my regex (the S \ d is because this part is always different in between). I also always have different colors. With the second regex I am now looking for the same values as in my first regex, but WITHOUT the two colors –  Aug 18 '20 at 17:31
  • @Koda so for clarification, you're looking to extract `S2w697` and `green`? Are all string ending with the colour? – ctwheels Aug 18 '20 at 17:32
  • I just want to find out whether my string is structured like the regex and in the second run I want to find out which strings are structured exactly that way but do not contain the two colors. "^ The thing is. * (S \ d). *" Should always be checked. You see my sample for the two goals in my first post (Sorry for my bad english) –  Aug 18 '20 at 17:33
  • So `^The thing is.*(S\d).*\b((?!blue|red)\w+)$`? – ctwheels Aug 18 '20 at 17:33
  • Thank you. When i Try this "$reg_exp = '^The thing is.*(S\d).*\b((?!blue|red)\w+)';" I get "Found" and not "Not found" –  Aug 18 '20 at 17:36
  • @Koda not clear what you mean by that. See it working [here](https://regex101.com/r/PTkklz/1) – ctwheels Aug 18 '20 at 17:37
  • @ctwheels Thank you. The problem is the $ and the end. I have remove this because one or two entries are not ended with the color –  Aug 18 '20 at 17:45
  • I thought this looked [familiar](https://stackoverflow.com/questions/63472005/regex-to-find-the-opposite) ;-) What is wrong with using a negative lookahead? https://regex101.com/r/23eBcJ/1 – The fourth bird Aug 18 '20 at 19:44

1 Answers1

0

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
Ryszard Czech
  • 18,032
  • 4
  • 24
  • 37