Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check VAT number for syntactical correctness with Regex possible?

I am trying to find a way to validate european VAT-IDs. They vary in lenght, sometimes have checksums and so on. Normaly I am using regex to validate simple strings - but this looks kind of very complex to me.

Wikipedia has a list of the different syntaxes:

  • https://de.wikipedia.org/wiki/Umsatzsteuer-Identifikationsnummer#Aufbau_der_Identifikationsnummer (german language)
  • https://en.wikipedia.org/wiki/VAT_identification_number (english language)

So before starting, wasting a lot of time and failing at the end, I would like to know from someone who uses regex more often than me, if it will be possible to pre-validate these numbers. If you think, VAT-ID syntax validation is not possible by regex, please give me an comprehensive example why not.

Thank you in advance.

Notes: Of course I know about validation XML-RPC validation of german ministry of finance (https://evatr.bff-online.de/eVatR/xmlrpc/), but this takes sometimes several minutes to receive an answer for the request. As well, they interrupt operation on this XML-RPC validation service from 23:00 to 05:00 o'clock Berlin time. Thats the reason why I would like to have a 2-step validation: first step for the syntax, second step (triggered by cron) with this XML-RPC.

like image 773
Andreas Witte Avatar asked Nov 10 '15 08:11

Andreas Witte


People also ask

How do you validate a RegEx pattern?

RegEx pattern validation can be added to text input type questions. To add validation, click on the Validation icon on the text input type question.

What is RegEx validator?

RegEx validation is essentially a syntax check which makes it possible to see whether an email address is spelled correctly, has no spaces, commas, and all the @s, dots and domain extensions are in the right place.

What does a German VAT number look like?

The general format of a German VAT number is: DE 123456789. The tax office splits VAT number into two: one for reporting VAT filings and general correspondence; the second for identification for companies undertaking EU cross border transactions (intra-community supplies).


2 Answers

There is a regex to validate the VAT number of the 27 EU countries provided at the Regular Expressions Cookbook, 2nd edition, 4.21. European VAT Numbers section.

There is no computing check with this regex, but it will still be able to check standalone strings that are likely to be EU VAT numbers.

Before validation, you should remove [-.●] or [^A-Z0-9] symbols. Then, use

(?xi)^(
(AT)?U[0-9]{8} |                              # Austria
(BE)?0[0-9]{9} |                              # Belgium
(BG)?[0-9]{9,10} |                            # Bulgaria
(HR)?[0-9]{11} |                              # Croatia
(CY)?[0-9]{8}[A-Z] |                          # Cyprus
(CZ)?[0-9]{8,10} |                            # Czech Republic
(DE)?[0-9]{9} |                               # Germany
(DK)?[0-9]{8} |                               # Denmark
(EE)?[0-9]{9} |                               # Estonia
(EL)?[0-9]{9} |                               # Greece
ES[A-Z][0-9]{7}(?:[0-9]|[A-Z]) |              # Spain
(FI)?[0-9]{8} |                               # Finland
(FR)?[0-9A-Z]{2}[0-9]{9} |                    # France
(GB)?([0-9]{9}([0-9]{3})?|[A-Z]{2}[0-9]{3}) | # United Kingdom
(HU)?[0-9]{8} |                               # Hungary
(IE)?[0-9]{7}[A-Z]{1,2}   |                   # Ireland
(IE)?[0-9][A-Z][0-9]{5}[A-Z] |                # Ireland (2)
(IT)?[0-9]{11} |                              # Italy
(LT)?([0-9]{9}|[0-9]{12}) |                   # Lithuania
(LU)?[0-9]{8} |                               # Luxembourg
(LV)?[0-9]{11} |                              # Latvia
(MT)?[0-9]{8} |                               # Malta
(NL)?[0-9]{9}B[0-9]{2} |                      # Netherlands
(PL)?[0-9]{10} |                              # Poland
(PT)?[0-9]{9} |                               # Portugal
(RO)?[0-9]{2,10} |                            # Romania
(SE)?[0-9]{12} |                              # Sweden
(SI)?[0-9]{8} |                               # Slovenia
(SK)?[0-9]{10}                                # Slovakia
)$

See the regex demo

I have added a Croatian VAT alternative here.

Note that if you expect the country codes to be present, remove ? quantifiers after the closing round brackets.

Whenver new countries join the European Union, or member countries change their rules for VAT numbers, the regex needs an update.

Note that the regex in the cookbook does not correspond to the Wiki's Irish VAT number definition.

Also, it is not possible to fully validate this with the regex because some VAT numbers require specific data that is either hard to retrieve or should be computed using regular programming language means:

  • French first 2 digits are a "key", and the French key is calculated as follow : Key = [ 12 + 3 * ( SIREN modulo 97 ) ] modulo 97, for example : Key = [ 12 + 3 * ( 404,833,048 modulo 97 ) ] modulo 97 = [12 + 3*56] modulo 97 = 180 modulo 97 = 83 so the tax number for 404,833,048 is FR 83,404,833,048 source from : www.insee.fr.
  • Finnish VAT last digit is a check digit utilizing MOD 11-2
  • Italian VAT has a province 3-symbol code (indices 8, 9, 10)
  • Slovakian VAT number must be divisible by 11
like image 106
Wiktor Stribiżew Avatar answered Oct 06 '22 01:10

Wiktor Stribiżew


My answer based on Wikipedia and Wiktor Stribiżew:

^(ATU[0-9]{8}|BE[01][0-9]{9}|BG[0-9]{9,10}|HR[0-9]{11}|CY[A-Z0-9]{9}|CZ[0-9]{8,10}|DK[0-9]{8}|EE[0-9]{9}|FI[0-9]{8}|FR[0-9A-Z]{2}[0-9]{9}|DE[0-9]{9}|EL[0-9]{9}|HU[0-9]{8}|IE([0-9]{7}[A-Z]{1,2}|[0-9][A-Z][0-9]{5}[A-Z])|IT[0-9]{11}|LV[0-9]{11}|LT([0-9]{9}|[0-9]{12})|LU[0-9]{8}|MT[0-9]{8}|NL[0-9]{9}B[0-9]{2}|PL[0-9]{10}|PT[0-9]{9}|RO[0-9]{2,10}|SK[0-9]{10}|SI[0-9]{8}|ES[A-Z]([0-9]{8}|[0-9]{7}[A-Z])|SE[0-9]{12}|GB([0-9]{9}|[0-9]{12}|GD[0-4][0-9]{2}|HA[5-9][0-9]{2}))$

I found that some Ireland VAT id wasn't working with mentioned answer. It's not 100% bulletproof (especially for GB government departments) but should do the work.

like image 33
marverix Avatar answered Oct 06 '22 01:10

marverix