请帮我设计一个正则表达式,可以匹配所有可能包含空格的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
请注意,如果意图是验证完整的字符串,则可以简化regex。
因为不需要使用否定的look-ahead (?!...)
。
单词边界\b
可以替换为行的开头^
和结尾$
。
^[A-Z]{2}[0-9]{2}(?:[ ]?[0-9]{4}){4}(?:[ ]?[0-9]{1,2})?$
此外,如果四个四个连接的数字组并不重要,那么它甚至可以更加简化。
^[A-Z]{2}(?:[ ]?[0-9]){18,20}$
额外信息
如果您需要匹配来自世界各地的IBAN号码?
那么IBAN的BBAN部分允许最多有30个数字或大写字母。参考
并且可以用空格、破折号或无分隔符的方式书写。
例如: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})?$
还要注意,纯正则表达式解决方案无法进行计算。
因此,需要额外的代码才能实际验证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))
});
i
标志以忽略大小写即可。 - LukStorms[A-Z]{2}\d{2} ?\d{4} ?\d{4} ?\d{4} ?\d{4} ?[\d]{0,2}
解释
[A-Z]{2}\d{2} ?
:2个大写字母后跟2个数字(可选空格)\d{4} ?
:4个数字,重复4次(可选空格)[\d]{0,2}
:0至2个数字[A-Z]\s*[A-Z]\s*\d\s*\d\s*.....等等。你的问题不太清楚,你应该更新它并添加更多的描述和示例。然而,如果我的答案回答了你的问题,并且你只想让空格变成可选的,你只需要在每个空格后面加上
?` 即可。 - Federico Piazza最好查找正确的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
DE\d{2}\s*\d{4}\s*\d{4}\s*\d{4}\s*\d{4}\s*\d{2}
将匹配您的第一个示例。 - Hannon Queiroz/(?<![A-Z])[A-Z]{2}(\h|\-)?[0-9]{2}(\h|\-)?[A-Z0-9](?:(\h|\-)?[A-Z0-9]){10,29}(?![A-Z0-9])/
- cottton