$re = '/^((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}))$/im';
$str = 'ATU12345678
BE0123456789
BG123456789
BG1234567890
CY12345678X
CY12345678L
CZ12345678
CZ123456789
CZ1234567890
DE123456789
DK12345678
EE123456789
EL123456789
GR123456789
ESX12345678
ES12345678X
ESX1234567X
FI12345678
FR12345678901
FRX1234567890
FR1X123456789
FRXX123456789
HU12345678
IE1234567WA
IE1234567FA
IT12345678901
LT123456789
LT123456789012
LU12345678
LV12345678901
MT12345678
NL123456789B01
NL123456789BO2
PL1234567890
PT123456789
RO1234567890
SE123456789012
SK1234567890';
preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);
// Print the entire match result
var_dump($matches);
Please keep in mind that these code samples are automatically generated and are not guaranteed to work. If you find any syntax errors, feel free to submit a bug report. For a full regex reference for PHP, please visit: http://php.net/manual/en/ref.pcre.php