1

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?

Tommy
  • 851
  • 9
  • 24

2 Answers2

2

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

The fourth bird
  • 154,723
  • 16
  • 55
  • 70
1

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

Tommy
  • 851
  • 9
  • 24