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?
CodePudding user response:
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
CodePudding user response:
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,}$