DebugPointer
Published on

Regex for EU VAT Number

Regex for EU VAT Number

The euro is the official currency of the European Union (EU) and a number of other European countries. It is denoted by the symbol "€" and is divided into 100 smaller units called cents. In this article let's understand how we can create a regex for euro and how regex can be matched for euro.

Regex (short for regular expression) is a powerful tool used for searching and manipulating text. It is composed of a sequence of characters that define a search pattern. Regex can be used to find patterns in large amounts of text, validate user input, and manipulate strings. It is widely used in programming languages, text editors, and command line tools.

Conditions to match EU VAT Number

  • VAT (Value-Added Tax) numbers in the European Union (EU) starts with two-letter country code
  • It is followed by the VAT number itself.
  • VAT number can consist of digits and alphabets
  • The length of the VAT number varies and it changes by the country
  • No other special characters are allowed

Regex for checking if EU VAT Number is valid or not

Regular Expression-

/^((AT)(U\d{8})|(BE)(0\d{9})|(BG)(\d{9,10})|(CY)(\d{8}[LX])|(CZ)(\d{8,10})|(DE)(\d{9})|(DK)(\d{8})|(EE)(\d{9})|(EL|GR)(\d{9})|(ES)([\dA-Z]\d{7}[\dA-Z])|(FI)(\d{8})|(FR)([\dA-Z]{2}\d{9})|(HU)(\d{8})|(IE)(\d{7}[A-Z]{2})|(IT)(\d{11})|(LT)(\d{9}|\d{12})|(LU)(\d{8})|(LV)(\d{11})|(MT)(\d{8})|(NL)(\d{9}(B\d{2}|BO2))|(PL)(\d{10})|(PT)(\d{9})|(RO)(\d{2,10})|(SE)(\d{12})|(SI)(\d{8})|(SK)(\d{10}))$/igm

Test string examples for the above regex-

Input StringMatch Output
YTFGUI&^%does not match
FR12345678901matches
IN12344532342does not match
DK12345678matches

More VAT values that match-

ATU12143178
BE0121431789
BG121431789
BG1214317890
CY12143178X
CY12143178L
CZ12143178
CZ121431789
CZ1214317890
DE121431789
IN12144312142
DK12143178
EE121431789
EL121431789
GR121431789
ESX12143178
ES12143178X
ESX1214317X
FI12143178
FR12143178901
FRX1214317890
FR1X121431789
FRXX121431789
HU12143178
IE1214317WA
IE1214317FA
IT12143178901
LT121431789
LT121431789012
LU12143178
LV12143178901
MT12143178
NL121431789B01
NL121431789BO2
PL1214317890
PT121431789
RO1214317890
SE121431789012
SK1214317890

Here is a detailed explanation of the above regex-

/^((AT)(U\d{8})|(BE)(0\d{9})|(BG)(\d{9,10})|(CY)(\d{8}[LX])|(CZ)(\d{8,10})|(DE)(\d{9})|(DK)(\d{8})|(EE)(\d{9})|(EL|GR)(\d{9})|(ES)([\dA-Z]\d{7}[\dA-Z])|(FI)(\d{8})|(FR)([\dA-Z]{2}\d{9})|(HU)(\d{8})|(IE)(\d{7}[A-Z]{2})|(IT)(\d{11})|(LT)(\d{9}|\d{12})|(LU)(\d{8})|(LV)(\d{11})|(MT)(\d{8})|(NL)(\d{9}(B\d{2}|BO2))|(PL)(\d{10})|(PT)(\d{9})|(RO)(\d{2,10})|(SE)(\d{12})|(SI)(\d{8})|(SK)(\d{10}))$/igm

^ asserts position at start of a line
1st Capturing Group ((AT)(U\d{8})|(BE)(0\d{9})|(BG)(\d{9,10})|(CY)(\d{8}[LX])|(CZ)(\d{8,10})|(DE)(\d{9})|(DK)(\d{8})|(EE)(\d{9})|(EL|GR)(\d{9})|(ES)([\dA-Z]\d{7}[\dA-Z])|(FI)(\d{8})|(FR)([\dA-Z]{2}\d{9})|(HU)(\d{8})|(IE)(\d{7}[A-Z]{2})|(IT)(\d{11})|(LT)(\d{9}|\d{12})|(LU)(\d{8})|(LV)(\d{11})|(MT)(\d{8})|(NL)(\d{9}(B\d{2}|BO2))|(PL)(\d{10})|(PT)(\d{9})|(RO)(\d{2,10})|(SE)(\d{12})|(SI)(\d{8})|(SK)(\d{10}))
1st Alternative (AT)(U\d{8})
2nd Capturing Group (AT)
3rd Capturing Group (U\d{8})
2nd Alternative (BE)(0\d{9})
4th Capturing Group (BE)
5th Capturing Group (0\d{9})
3rd Alternative (BG)(\d{9,10})
6th Capturing Group (BG)
7th Capturing Group (\d{9,10})
4th Alternative (CY)(\d{8}[LX])
8th Capturing Group (CY)
9th Capturing Group (\d{8}[LX])
5th Alternative (CZ)(\d{8,10})
10th Capturing Group (CZ)
11th Capturing Group (\d{8,10})
6th Alternative (DE)(\d{9})
12th Capturing Group (DE)
13th Capturing Group (\d{9})
7th Alternative (DK)(\d{8})
14th Capturing Group (DK)
15th Capturing Group (\d{8})
8th Alternative (EE)(\d{9})
16th Capturing Group (EE)
17th Capturing Group (\d{9})
9th Alternative (EL|GR)(\d{9})
18th Capturing Group (EL|GR)
19th Capturing Group (\d{9})
10th Alternative (ES)([\dA-Z]\d{7}[\dA-Z])
20th Capturing Group (ES)
21st Capturing Group ([\dA-Z]\d{7}[\dA-Z])
11th Alternative (FI)(\d{8})
22nd Capturing Group (FI)
23rd Capturing Group (\d{8})
12th Alternative (FR)([\dA-Z]{2}\d{9})
24th Capturing Group (FR)
25th Capturing Group ([\dA-Z]{2}\d{9})
13th Alternative (HU)(\d{8})
26th Capturing Group (HU)
27th Capturing Group (\d{8})
14th Alternative (IE)(\d{7}[A-Z]{2})
28th Capturing Group (IE)
29th Capturing Group (\d{7}[A-Z]{2})
15th Alternative (IT)(\d{11})
30th Capturing Group (IT)
31st Capturing Group (\d{11})
16th Alternative (LT)(\d{9}|\d{12})
32nd Capturing Group (LT)
33rd Capturing Group (\d{9}|\d{12})
17th Alternative (LU)(\d{8})
34th Capturing Group (LU)
35th Capturing Group (\d{8})
18th Alternative (LV)(\d{11})
36th Capturing Group (LV)
37th Capturing Group (\d{11})
19th Alternative (MT)(\d{8})
38th Capturing Group (MT)
39th Capturing Group (\d{8})
20th Alternative (NL)(\d{9}(B\d{2}|BO2))
40th Capturing Group (NL)
41st Capturing Group (\d{9}(B\d{2}|BO2))
21st Alternative (PL)(\d{10})
43rd Capturing Group (PL)
44th Capturing Group (\d{10})
22nd Alternative (PT)(\d{9})
45th Capturing Group (PT)
46th Capturing Group (\d{9})
23rd Alternative (RO)(\d{2,10})
47th Capturing Group (RO)
48th Capturing Group (\d{2,10})
24th Alternative (SE)(\d{12})
49th Capturing Group (SE)
50th Capturing Group (\d{12})
25th Alternative (SI)(\d{8})
26th Alternative (SK)(\d{10})
$ asserts position at the end of a line
Global pattern flags
i modifier: insensitive. Case insensitive match (ignores case of [a-zA-Z])
g modifier: global. All matches (don't return after first match)
m modifier: multi line. Causes ^ and $ to match the begin/end of each line (not only begin/end of string)

Hope this article was useful to check if EU VAT Number is valid or not. If you have any doubts or suggestions, feel free to comment below.