IBAN 正则表达式设计



请帮我设计将所有IBAN与所有可能的空格相匹配的正则表达式。因为我找到了那个,但它不适用于空格。

[a-zA-Z]{2}[0-9]{2}[a-zA-Z0-9]{4}[0-9]{7}([a-zA-Z0-9]?){0,16}

我至少需要这种格式:

DE89 3704 0044 0532 0130 00
AT61 1904 3002 3457 3201
FR14 2004 1010 0505 0001 3

只是为了在文本中找到来自这些国家/地区的示例 IBAN:
以 2 个字母开头,然后以 2 位数字开头.
然后在每 4 位数字之前留出一个空格,可以选择以 1 或 2 位数字结尾:

b[A-Z]{2}[0-9]{2}(?:[ ]?[0-9]{4}){4}(?!(?:[ ]?[0-9]){3})(?:[ ]?[0-9]{1,2})?b    

正则表达式101测试在这里

请注意,如果目的是验证完整的字符串,则可以简化正则表达式.
由于不需要负的预(?!...),因此.
并且单词边界b可以用行的开始^和结束$替换。

^[A-Z]{2}[0-9]{2}(?:[ ]?[0-9]{4}){4}(?:[ ]?[0-9]{1,2})?$

此外,如果拥有 4 组 4 个连接的数字并不重要,则可以进一步简化。

^[A-Z]{2}(?:[ ]?[0-9]){18,20}$

额外

如果您需要匹配来自世界各地的 IBAN 号码?
那么 IBAN 的 BBAN 部分最多可以有 30 个数字或大写字母。 Reference
可以用空格或破折号书写,也可以用空格或破折号书写,也可以不写。
例如:CC12-XXXX-12XX-1234-5678-9012-3456-7890-123

因此,将完整字符串与长 IBAN 匹配的正则表达式模式会变得更长一些。

^([A-Z]{2}[ -]?[0-9]{2})(?=(?:[ -]?[A-Z0-9]){9,30}$)((?:[ -]?[A-Z0-9]{3,5}){2,7})([ -]?[A-Z0-9]{1,3})?$

正则表达式101测试在这里

另请注意,纯正则表达式解决方案无法进行计算.
因此,要实际验证IBAN编号,则需要额外的代码。

示例 Javascript 片段:

function smellsLikeIban(str){
return /^([A-Z]{2}[ -]?[0-9]{2})(?=(?:[ -]?[A-Z0-9]){9,30}$)((?:[ -]?[A-Z0-9]{3,5}){2,7})([ -]?[A-Z0-9]{1,3})?$/.test(str);
}
function validateIbanChecksum(iban) {       
const ibanStripped = iban.replace(/[^A-Z0-9]+/gi,'') //keep numbers and letters only
.toUpperCase(); //calculation expects upper-case
const m = ibanStripped.match(/^([A-Z]{2})([0-9]{2})([A-Z0-9]{9,30})$/);
if(!m) return false;

const numbericed = (m[3] + m[1] + m[2]).replace(/[A-Z]/g,function(ch){
//replace upper-case characters by numbers 10 to 35
return (ch.charCodeAt(0)-55); 
});
//The resulting number would be to long for javascript to handle without loosing precision.
//So the trick is to chop the string up in smaller parts.
const mod97 = numbericed.match(/d{1,7}/g)
.reduce(function(total, curr){ return Number(total + curr)%97},'');
return (mod97 === 1);
};
var arr = [
'DE89 3704 0044 0532 0130 00', // ok
'AT61 1904 3002 3457 3201', // ok
'FR14 2004 1010 0505 0001 3', // wrong checksum
'GB82-WEST-1234-5698-7654-32', // ok
'NL20INGB0001234567', // ok
'XX00 1234 5678 9012 3456 7890 1234 5678 90', // only smells ok
'YY00123456789012345678901234567890', // only smells ok
'NL20-ING-B0-00-12-34-567', // stinks, but still a valid checksum
'XX22YYY1234567890123', // wrong checksum again
'droid@i.ban' // This Is Not The IBAN You Are Looking For
];
arr.forEach(function (str) {
console.log('['+ str +'] Smells Like IBAN:    '+ smellsLikeIban(str));
console.log('['+ str +'] Valid IBAN Checksum: '+ validateIbanChecksum(str))
});

这里有一个可能适用于您提供的模式的建议:

[A-Z]{2}d{2} ?d{4} ?d{4} ?d{4} ?d{4} ?[d]{0,2}

在正则表达式101上尝试一下


解释

  • [A-Z]{2}d{2} ?2 个大写字母后跟 2 位数字(可选空格)
  • d{4} ?4 位数字,重复 4 次(可选空格)
  • [d]{0,2}0 到 2 位数字

您可以使用如下正则表达式:

^[A-Z]{2}d{2} (?:d{4} ){3}d{4}(?: dd?)?$

工作演示

这将仅匹配那些字符串格式

最好查找正确的 IBAN 编号的规格。但是,如果您想拥有一个类似于现有正则表达式但带有空格的正则表达式,则可以使用以下正则表达式:

^[a-zA-Z]{2}[0-9]{2}s?[a-zA-Z0-9]{4}s?[0-9]{4}s?[0-9]{3}([a-zA-Z0-9]s?[a-zA-Z0-9]{0,4}s?[a-zA-Z0-9]{0,4}s?[a-zA-Z0-9]{0,4}s?[a-zA-Z0-9]{0,3})?$

这是一个活生生的例子:https://regex101.com/r/ZyIPLD/1

最新更新