IBAN的正则表达式,允许包含空格并检查长度是否准确

12

我需要检查一个输入字段的德国IBAN。用户应该被允许留下空格,并且输入应该被验证是否以DE开头,然后是20个确切的字符数字。

如果不允许空格,我尝试了...

^[DE]{2}([0-9a-zA-Z]{20})$

但是我找不到在哪里以及如何添加“允许任何位置的空格”。

这应该很简单,但是我就是找不到解决方案。

谢谢帮助!


1
你使用的是什么编程语言?从字符串中删除所有空格是否是一个合适的解决方案?另外,FYI,[DE]{2}匹配DDED:请参见http://www.regular-expressions.info/charclass.html。 - Robin
1
正如我在答案中所说的那样,您并没有使用正确的工具来完成任务。您不应该仅针对格式检查重要的内容,例如IBAN,而是通过计算校验和来检查整个代码的有效性,这与正则表达式检查的算法复杂度相同。 - zmo
非常感谢!我们在后端确实会验证正确的IBAN格式,但也希望能够在前端引导用户。 - viddity
1
不要试图指导,只需验证它。重申一遍:校验和计算比正则表达式更快、更轻便、更容易实现,是验证 IBAN 输入的最佳方式! - zmo
7个回答

32

这里是来自70个国家的IBAN列表。我使用基于https://en.wikipedia.org/wiki/International_Bank_Account_Number的Python脚本生成它。

AL[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){2}([a-zA-Z0-9]{4}\s?){4}\s?
AD[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){2}([a-zA-Z0-9]{4}\s?){3}\s?
AT[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){4}\s?
AZ[a-zA-Z0-9]{2}\s?([a-zA-Z0-9]{4}\s?){1}([0-9]{4}\s?){5}\s?
BH[a-zA-Z0-9]{2}\s?([a-zA-Z]{4}\s?){1}([a-zA-Z0-9]{4}\s?){3}([a-zA-Z0-9]{2})\s?
BY[a-zA-Z0-9]{2}\s?([a-zA-Z0-9]{4}\s?){1}([0-9]{4}\s?){5}\s?
BE[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){3}\s?
BA[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){4}\s?
BR[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){5}([0-9]{3})([a-zA-Z]{1}\s?)([a-zA-Z0-9]{1})\s?
BG[a-zA-Z0-9]{2}\s?([a-zA-Z]{4}\s?){1}([0-9]{4}\s?){1}([0-9]{2})([a-zA-Z0-9]{2}\s?)([a-zA-Z0-9]{4}\s?){1}([a-zA-Z0-9]{2})\s?
CR[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){4}([0-9]{2})\s?
HR[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){4}([0-9]{1})\s?
CY[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){2}([a-zA-Z0-9]{4}\s?){4}\s?
CZ[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){5}\s?
DK[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){3}([0-9]{2})\s?
DO[a-zA-Z0-9]{2}\s?([a-zA-Z]{4}\s?){1}([0-9]{4}\s?){5}\s?
TL[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){4}([0-9]{3})\s?
EE[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){4}\s?
FO[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){3}([0-9]{2})\s?
FI[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){3}([0-9]{2})\s?
FR[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){2}([0-9]{2})([a-zA-Z0-9]{2}\s?)([a-zA-Z0-9]{4}\s?){2}([a-zA-Z0-9]{1})([0-9]{2})\s?
GE[a-zA-Z0-9]{2}\s?([a-zA-Z0-9]{2})([0-9]{2}\s?)([0-9]{4}\s?){3}([0-9]{2})\s?
DE[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){4}([0-9]{2})\s?
GI[a-zA-Z0-9]{2}\s?([a-zA-Z]{4}\s?){1}([a-zA-Z0-9]{4}\s?){3}([a-zA-Z0-9]{3})\s?
GR[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){1}([0-9]{3})([a-zA-Z0-9]{1}\s?)([a-zA-Z0-9]{4}\s?){3}([a-zA-Z0-9]{3})\s?
GL[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){3}([0-9]{2})\s?
GT[a-zA-Z0-9]{2}\s?([a-zA-Z0-9]{4}\s?){1}([a-zA-Z0-9]{4}\s?){5}\s?
HU[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){6}\s?
IS[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){5}([0-9]{2})\s?
IE[a-zA-Z0-9]{2}\s?([a-zA-Z0-9]{4}\s?){1}([0-9]{4}\s?){3}([0-9]{2})\s?
IL[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){4}([0-9]{3})\s?
IT[a-zA-Z0-9]{2}\s?([a-zA-Z]{1})([0-9]{3}\s?)([0-9]{4}\s?){1}([0-9]{3})([a-zA-Z0-9]{1}\s?)([a-zA-Z0-9]{4}\s?){2}([a-zA-Z0-9]{3})\s?
JO[a-zA-Z0-9]{2}\s?([a-zA-Z]{4}\s?){1}([0-9]{4}\s?){5}([0-9]{2})\s?
KZ[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){3}([0-9]{1})([a-zA-Z0-9]{3}\s?)([a-zA-Z0-9]{4}\s?){2}([a-zA-Z0-9]{2})\s?
XK[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){1}([0-9]{4}\s?){2}([0-9]{2})([0-9]{2}\s?)\s?
KW[a-zA-Z0-9]{2}\s?([a-zA-Z]{4}\s?){1}([a-zA-Z0-9]{4}\s?){5}([a-zA-Z0-9]{2})\s?
LV[a-zA-Z0-9]{2}\s?([a-zA-Z]{4}\s?){1}([a-zA-Z0-9]{4}\s?){3}([a-zA-Z0-9]{1})\s?
LB[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){1}([a-zA-Z0-9]{4}\s?){5}\s?
LI[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){1}([0-9]{1})([a-zA-Z0-9]{3}\s?)([a-zA-Z0-9]{4}\s?){2}([a-zA-Z0-9]{1})\s?
LT[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){4}\s?
LU[a-zA-Z0-9]{2}\s?([0-9]{3})([a-zA-Z0-9]{1}\s?)([a-zA-Z0-9]{4}\s?){3}\s?
MK[a-zA-Z0-9]{2}\s?([0-9]{3})([a-zA-Z0-9]{1}\s?)([a-zA-Z0-9]{4}\s?){2}([a-zA-Z0-9]{1})([0-9]{2})\s?
MT[a-zA-Z0-9]{2}\s?([a-zA-Z]{4}\s?){1}([0-9]{4}\s?){1}([0-9]{1})([a-zA-Z0-9]{3}\s?)([a-zA-Z0-9]{4}\s?){3}([a-zA-Z0-9]{3})\s?
MR[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){5}([0-9]{3})\s?
MU[a-zA-Z0-9]{2}\s?([a-zA-Z]{4}\s?){1}([0-9]{4}\s?){4}([0-9]{3})([a-zA-Z]{1}\s?)([a-zA-Z]{2})\s?
MC[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){2}([0-9]{2})([a-zA-Z0-9]{2}\s?)([a-zA-Z0-9]{4}\s?){2}([a-zA-Z0-9]{1})([0-9]{2})\s?
MD[a-zA-Z0-9]{2}\s?([a-zA-Z0-9]{2})([a-zA-Z0-9]{2}\s?)([a-zA-Z0-9]{4}\s?){4}\s?
ME[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){4}([0-9]{2})\s?
NL[a-zA-Z0-9]{2}\s?([a-zA-Z]{4}\s?){1}([0-9]{4}\s?){2}([0-9]{2})\s?
NO[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){2}([0-9]{3})\s?
PK[a-zA-Z0-9]{2}\s?([a-zA-Z0-9]{4}\s?){1}([0-9]{4}\s?){4}\s?
PS[a-zA-Z0-9]{2}\s?([a-zA-Z0-9]{4}\s?){1}([0-9]{4}\s?){5}([0-9]{1})\s?
PL[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){6}\s?
PT[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){5}([0-9]{1})\s?
QA[a-zA-Z0-9]{2}\s?([a-zA-Z]{4}\s?){1}([a-zA-Z0-9]{4}\s?){5}([a-zA-Z0-9]{1})\s?
RO[a-zA-Z0-9]{2}\s?([a-zA-Z]{4}\s?){1}([a-zA-Z0-9]{4}\s?){4}\s?
SM[a-zA-Z0-9]{2}\s?([a-zA-Z]{1})([0-9]{3}\s?)([0-9]{4}\s?){1}([0-9]{3})([a-zA-Z0-9]{1}\s?)([a-zA-Z0-9]{4}\s?){2}([a-zA-Z0-9]{3})\s?
SA[a-zA-Z0-9]{2}\s?([0-9]{2})([a-zA-Z0-9]{2}\s?)([a-zA-Z0-9]{4}\s?){4}\s?
RS[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){4}([0-9]{2})\s?
SK[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){5}\s?
SI[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){3}([0-9]{3})\s?
ES[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){5}\s?
SE[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){5}\s?
CH[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){1}([0-9]{1})([a-zA-Z0-9]{3}\s?)([a-zA-Z0-9]{4}\s?){2}([a-zA-Z0-9]{1})\s?
TN[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){5}\s?
TR[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){1}([0-9]{1})([a-zA-Z0-9]{3}\s?)([a-zA-Z0-9]{4}\s?){3}([a-zA-Z0-9]{2})\s?
AE[a-zA-Z0-9]{2}\s?([0-9]{3})([0-9]{1}\s?)([0-9]{4}\s?){3}([0-9]{3})\s?
GB[a-zA-Z0-9]{2}\s?([a-zA-Z]{4}\s?){1}([0-9]{4}\s?){3}([0-9]{2})\s?
VA[a-zA-Z0-9]{2}\s?([0-9]{3})([0-9]{1}\s?)([0-9]{4}\s?){3}([0-9]{2})\s?
VG[a-zA-Z0-9]{2}\s?([a-zA-Z0-9]{4}\s?){1}([0-9]{4}\s?){4}\s? 

不知道为什么会有人踩。这个列表至少非常有用。这些看起来是正确的。而德语正则表达式在你的答案中。 - Bob van den Berg

31

因为你应该使用合适的工具来完成合适的任务:你不应该依赖于正则表达式来验证IBAN(国际银行账号)号码,而是应该使用IBAN校验算法来检查整个代码是否正确,使任何正则表达式都变得多余和冗余。:删除所有空格,重新排列代码,转换为整数,并计算余数,在这里最好解释了

尽管如此,为了有趣而尝试回答你的问题:

那么怎么样:

^DE([0-9a-zA-Z]\s?){20}$

其唯一的区别是允许在每个字母数字字符出现后加上一个空格(或不加)。

这里 是可视化结果:

正则表达式可视化

编辑:对于此正则表达式,从 @ulugbex-umirov: (?:\s*[0-9a-zA-Z]\s*) 唯一的区别是进行了一个前瞻性检查,以查看 ISO 国家代码和仅由数字组成的校验和之间是否有空格,而我故意不支持此功能。

事实上,为了支持正确的 IBAN 语法,它由 4 个字符组成组,请参见维基百科页面

^DE\d{2}\s?([0-9a-zA-Z]{4}\s?){4}[0-9a-zA-Z]{2}$

正则表达式可视化

示例

如果你的用户界面是使用Javascript编写的,你可以使用该库来进行国际银行账号(IBAN)验证:

<script src="iban.js"></script>
<script>
    // the API is now accessible from the window.IBAN global object
    IBAN.isValid('hello world'); // false
    IBAN.isValid('BE68539007547034'); // true
</script>

所以你知道这是一个有效的IBAN,并且可以在数据发送到后端之前进行验证。更简单,更轻便,更优雅……还需要做什么呢?


非常感谢您的快速和非常有帮助的回答!我们在后端也进行验证。正则表达式是额外的,用于用户指导。 - viddity
不对,校验和验证非常轻巧,甚至比正则表达式检查还要轻!它可以帮助用户检测任何真正的错误,而不仅仅是格式错误,因为格式错误经常是一个问题。此外,您可以支持任何校验和,而不仅仅是德国的校验和...我曾经是许多只接受来自说德语国家付款的德国网站的客户,而我并不住在这些国家之一...我们在欧洲,我们有SEPA和IBAN! :-) - zmo
1
顺便提一下,如果你的用户界面是用JavaScript编写的,有一堆JS库可以实现校验和计算:这里那里或者这里 - zmo
1
@fbitterlich,你在哪里发布了关于这个 bug 的详细信息?我在 arhs/iban.js 的 Github 页面上没有看到它作为一个问题。 - kluka
1
@zmo:这个答案让我想要能够点赞两次 :-) - Andresch Serj
显示剩余5条评论

6

4

这是匹配德国IBAN账号的正确正则表达式:

DE\d{2}[ ]\d{4}[ ]\d{4}[ ]\d{4}[ ]\d{4}[ ]\d{2}|DE\d{20}

Pass:   DE89 3704 0044 0532 0130 00|||DE89370400440532013000
Fail:   DE89-3704-0044-0532-0130-00

3
我能提供的最简单解决方案如下:
^DE(\s*[[:alnum:]]){20}\s*$

特别是,你的初始代码 [DE]{2} 是错误的,因为它允许 'DD'、'EE'、'ED' 以及预期的 'DE'。


1

允许在任何地方输入任意数量的空格:

^ *D *E( *[A-Za-z0-9]){20} *$

您希望允许小写字母,那么 DE 是否也会是小写呢?

^ *[Dd] *[Ee]( *[A-Za-z0-9]){20} *$
  • ^ 匹配字符串的开头
  • $ 结束锚点
  • 在每个字符之间有可选的空格 *
  • [字符类] 定义了一组/范围的字符

为了允许每个字符之间最多有一个空格,请将 量词 * (任意数量) 替换为 ? (0或1)。如果支持,可以使用 \s 速记符 来匹配 [ \t\r\n\f] 而不仅仅是空格。

在regex101.com上测试, 另请参见 SO regex FAQ


0
使用Google Apps Script,我将Laurent的代码github粘贴到一个脚本中,并添加了以下代码进行测试。
// Use the Apps Script IDE's "Run" menu to execute this code.
// Then look at the View > Logs menu to see execution results.

function myFunction() {
//https://github.com/arhs/iban.js/blob/master/README.md
// var IBAN = require('iban');
var t1 = IBAN.isValid('hello world'); // false
var t2 = IBAN.isValid('BE68539007547034'); // true
var t3 = IBAN.isValid('BE68 5390 0754 7034'); // true

Logger.log("Test 1 = %s", t1);
Logger.log("Test 2 = %s", t2);
Logger.log("Test 3 = %s", t3);
}

运行示例代码所需的唯一步骤是将require('iban')这一行注释掉: // var IBAN = require('iban'); 最后,我使用服务器处理程序来验证IBAN输入,而不是使用客户端处理程序尝试进行正则表达式验证。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接