Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Regex OR operator to solve 2 conditions

I am trying to combine 2 regular expressions into 1 with the OR operator: |

I have one that checks for match of a letter followed by 8 digits:

Regex.IsMatch(s, "^[A-Z]\d{8}$")


I have another that checks for simply 9 digits:

Regex.IsMatch(s, "^\d{9}$")


Now, Instead of doing:

If Not Regex.IsMatch(s, "^[A-Z]\d{8}$") AndAlso
   Not Regex.IsMatch(s, "^\d{9}$") Then 
    ...
End If


I thought I could simply do:

If Not Regex.IsMatch(s, "^[A-Z]\d{8}|\d{9}$") Then
    ...
End If


Apparently I am not combining the two correctly and apparently I am horrible at regular expressions. Any help would be much appreciated.

And for those wondering, I did take a glance at How to combine 2 conditions and more in regex and I am still scratching my head.

like image 624
Code Maverick Avatar asked Apr 10 '12 18:04

Code Maverick


4 Answers

The | operator has a high precedence and in your original regex will get applied first. You should be combining the two regex's w/ grouping parentheses to make the precedence clear. As in:

"^(([A-Z]\d{8})|(\d{9}))$"
like image 108
Mike Ryan Avatar answered Sep 29 '22 10:09

Mike Ryan


How about using ^[A-Z0-9]\d{8}$ ?

like image 34
Mike C Avatar answered Sep 29 '22 10:09

Mike C


I think you want to group the conditions:

Regex.IsMatch(s, "^(([A-Z]\d{8})|(\d{9}))$")

The ^ and $ represent the beginning and end of the line, so you don't want them considered in the or condition. The parens allow you to be explicit about "everything in this paren" or "anything in this other paren"

like image 12
Chris Shain Avatar answered Sep 29 '22 12:09

Chris Shain


@MikeC's offering seems the best:

^[A-Z0-9]\d{8}$

...but as to why your expression is not working the way you might expect, you have to understand that the | "or" or "alternation" operator has a very high precedence - the only higher one is the grouping construct, I believe. If you use your example:

^[A-Z]\d{8}|\d{9}$

...you're basically saying "match beginning of string, capital letter, then 8 digits OR match 9 digits then end of string" -- if, instead you mean "match beginning of string, then a capital letter followed by 8 digits then the end of string OR the beginning of the string followed by 9 digits, then the end of string", then you want one of these:

^([A-Z]\d{8}|\d{9})$
^[A-Z]\d{8}$|^\d{9}$

Hope this is helpful for your understanding

like image 9
Code Jockey Avatar answered Sep 29 '22 12:09

Code Jockey