ongahong
ongahong

Reputation: 23

How to use regular expression to match any thing not in the a list?

I have a list I want to not match, say: 123, 456 and 78

If the the text is "456", no match.
if the text is "123;456", no match
if the text is "123;78", no match
if the text is "123;34", match
if the text is "56", match

So as long as the text has any item not in the list, then it's match.

The closest I can come up is:

^(?!(;)?(?:123|456|78)(;)?$).*$ 

But it fails for "123;456".

So what's the correct regex to achieve it?

Thanks

Upvotes: 2

Views: 116

Answers (4)

user557597
user557597

Reputation:

Edit: I'm sure we will get to the bottom of this.

These updated regexes are the maximum throw of coverage available.
They use the standard fast un-roll method. As the requirements become more clear,
start deleting substrings and/or modifiers as needed, ultimately keeping the same
overall structure.

Good Luck!

 # ======================================================
 # Sample contains any chars
 # @"^(?s)(?!;*(?:123|456|78)(?:;+(?:123|456|78))*;*$).+$"

 ^  
 (?s)
 (?!
      ;*
      (?: 123 | 456 | 78 )
      (?:
           ;+ 
           (?: 123 | 456 | 78 )
      )*
      ;*
      $ 
 )
 .+ 
 $ 

 # ======================================================
 # Sample contains semi-colon and digits only
 # @"^(?!;*(?:123|456|78)(?:;+(?:123|456|78))*;*$)[;0-9]+$"

 ^ 
 (?!
      ;*
      (?: 123 | 456 | 78 )
      (?:
           ;+
           (?: 123 | 456 | 78 )
      )*
      ;*
      $ 
 )
 [;0-9]+ 
 $

Upvotes: 0

Sam Harwell
Sam Harwell

Reputation: 99889

Since your question is not completely clear, I made several assumptions based on your examples.

  • I assume each item in the list is a non-empty sequence of decimal digits; specifically a match to the following:

    [0-9]+
    
  • I assume the items of the list are separated by a single ; character; no other leading or terminating characters or whitespace are allowed anywhere in the input.

I break this down into three portions:

  1. Any leading item, whether or not it's in the list:

    (?:[0-9]+;)*
    
  2. One required item which is not in the list:

    (?:(?!(123|456|78)\b)[0-9]+)
    
  3. Any trailing items, whether or not they are in the list:

    (?:;[0-9]+)*
    

Combining them we get the final result:

^(?:[0-9]+;)*(?:(?!(123|456|78)\b)[0-9]+)(?:;[0-9]+)*$

Upvotes: 0

anubhava
anubhava

Reputation: 785276

I think you can use word boundaries:

\b(?!(?:123|456|78))[^;\n]+

RegEx Demo

Upvotes: 0

Charles
Charles

Reputation: 11479

The question seems to be: match any string of characters unless it is of the form "x;y;...;z" with x, y, z, etc. one of 123, 456, and 78.

I believe this regular expression will do the trick:

^(..?;)*([^147]|1[^2]|4[^5]|7[^8]|12[^3]|45[^6]|[14]$|12$|45$)

Remember: just because regular expressions can do something (like negate a regular expression) doesn't mean they should be used to do that thing. In this case you should probably explode the string on ; and check each term until you find a non-match.

Upvotes: 1

Related Questions