Regex fallback if multiple conditions were not met, fallback must not match any of previous conditions

Viewed 42

I am creating an IBAN checker that currently works fine: it recognizes the first 2 characters (e.g. DE or GB) and according to the matched country code checks the specific IBAN structure (DE is followed by numbers only, while GB has a some letters somewhere in there). So those things get checked perfectly fine.

Here the working code without a fallback: https://regex101.com/r/HqThjy/1

^(?:GB\d{2}[A-Z]{4}\d{14}|DE\d{20})$

this matches:
DE12312341212312312312
GB12ASDF12312312312311

But I want to integrate a fallback for when non of my set countries I want to check specifically (let's stick with DE and GB) are matched, for example Norway with its code NO. My current idea of a fallback ends my example with an ELSE condition but this matches also a false DE and GB string: https://regex101.com/r/HqThjy/3

^(?:GB\d{2}[A-Z]{4}\d{14}|DE\d{20})|[A-Z]{2}(?:[A-Z]|\d){13,}$

this matches:
DE12312341212312312312
GB12ASDF12312312312311
NO1212121212121
DE1231234121231 <- should not be a match
GB1231231231231 <- should not be a match

Is there maybe a way to tell regex, if it does not match "DE or GB" then check against anything, but not DE/GB?

2 Answers

In case when using Javascript and a negative lookbehind is not supported, you can also turn the lookbehind in a lookahead, and change the last alternation to a character class

^(?:GB\d{2}[A-Z]{4}\d{14}|DE\d{20})|(?!DE|GB)[A-Z]{2}[A-Z\d]{13,}$

Regex demo

While typing the question and preparing the examples I stumbled over this SO question which has the solution: negative lookbehind

I adapted my code to look like this: https://regex101.com/r/HqThjy/4

^(?:GB\d{2}[A-Z]{4}\d{14}|DE\d{20})|[A-Z]{2}(?<!DE|GB)(?:[A-Z]|\d){13,}$

This [A-Z]{2}(?<!DE|GB) does the trick. It looks for 2 uppercase letters and only proceeds, if the preceding 2 characters are not DE or GB. More about Lookbehind here: regular-expressions.info

Related