IBAN正则表达式设计

Max*_*mus 9 regex iban

请帮我设计一下将所有可能的空白与所有IBAN匹配的正则表达式.因为我发现了一个,但它不适用于空格.

[a-zA-Z]{2}[0-9]{2}[a-zA-Z0-9]{4}[0-9]{7}([a-zA-Z0-9]?){0,16}
Run Code Online (Sandbox Code Playgroud)

我至少需要这些格式:

DE89 3704 0044 0532 0130 00
AT61 1904 3002 3457 3201
FR14 2004 1010 0505 0001 3
Run Code Online (Sandbox Code Playgroud)

Luk*_*rms 21

仅举例来自这些国家的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    
Run Code Online (Sandbox Code Playgroud)

regex101在这里测试

请注意,如果要验证完整的字符串,则可以简化正则表达式.
因为(?!...)那时不需要负面预测.
单词边界\b可以由行的开头^和结尾替换$.

^[A-Z]{2}[0-9]{2}(?:[ ]?[0-9]{4}){4}(?:[ ]?[0-9]{1,2})?$
Run Code Online (Sandbox Code Playgroud)

而且,如果具有4组4个连接数字并不重要,那么可以更简化那个.

^[A-Z]{2}(?:[ ]?[0-9]){18,20}$
Run Code Online (Sandbox Code Playgroud)

备注

但是,如果你想匹配世界各地的IBAN号码?
然后允许IBAN的BBAN部分具有最多30个数字或大写字母. 参考
和可以用空格或短划线写入或两者之间没有任何内容.
例如:CC12 XXXX 12XX 1234 1234 1234 1234 1234 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})?$
Run Code Online (Sandbox Code Playgroud)

regex101在这里测试

另请注意,纯正则表达式解决方案无法进行计算.
因此,要实际验证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', // smells ok
 'YY00123456789012345678901234567890', // smells ok
 'NL20-ING-B0-00-12-34-567', // wrong format, but valid checksum
 'XX22YYY1234567890123', // wrong checksum
 'foo@i.ban' // Not even smells like IBAN
];
arr.forEach(function (str) {
  console.log('['+ str +'] Smells Like IBAN:    '+ smellsLikeIban(str));
  console.log('['+ str +'] Valid IBAN Checksum: '+ validateIbanChecksum(str))
});
Run Code Online (Sandbox Code Playgroud)


Mis*_*lis 6

以下建议可能适用于您提供的模式:

[A-Z]{2}\d{2} ?\d{4} ?\d{4} ?\d{4} ?\d{4} ?[\d]{0,2}
Run Code Online (Sandbox Code Playgroud)

在regex101上试试吧


说明

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


Fed*_*zza 2

您可以使用这样的正则表达式:

^[A-Z]{2}\d{2} (?:\d{4} ){3}\d{4}(?: \d\d?)?$
Run Code Online (Sandbox Code Playgroud)

工作演示

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