BIC校验的正则表达式

14
我为php函数preg_match写了一个正则表达式,如下所示:
^([a-zA-Z]){4}([a-zA-Z]){2}([0-9a-zA-Z]){2}([0-9a-zA-Z]{3})?$^

现在我需要检查一个BIC字符串的一致性。

有些地方出了问题,它总是正确的。我不知道为什么。

我使用的代码类似于这样:

/**
 * Checks the correct format from the 
 * @param string $bic
 * @return boolean
 */
public function checkBic($bic)
{
    $bic = $this->cleanFromSeparators($bic);
    if (preg_match($this->getBicCompare(), $bic)) {
        return true;
    } else {
        return false;
    }
}

private function getBicCompare()
{
    return "^([a-zA-Z]){4}([a-zA-Z]){2}([0-9a-zA-Z]){2}([0-9a-zA-Z]{3})?$^";
}

编辑:

这里是来自swift账户的BIC格式参考资料:

http://www.sage.co.uk/sage1000v2_1/form_help/workingw/subfiles/iban_and_bic.htm

http://en.wikipedia.org/wiki/ISO_9362

http://www.swift.com/products_services/bic_and_iban_format_registration_bic_details?rdct=t

一个BIC示例为:

NOLADE21STS

OPSKATWW

如果字符串符合以下代码,则正则表达式仅返回true: 长度为8或11个字符,包含以下内容:

银行代码-4个字母字符 国家代码-2个字母 地点代码-2个字母数字字符(除零外) 分支机构代码-3个字母数字字符

这些是规格说明。

因此,长度可以是11或8,前4个可以是任何内容,然后必须是2个字母,然后是2个数字和可选的3个字母数字。

以下是无效的:

abcdefxx

abcdefxxyyy

这些也是无效的:

aaaa11xx

aaaa11xxyyy

等等。


1
请问您能否提供更多信息?例如,正确的BIC应该长成什么样子,不应该长成什么样子... - Paolo Stefan
稍等一下,我马上就愿意 :) - Sangoku
1
@Sangoku,你能给我们举个例子吗?哪些本不应该起作用的却起作用了? - Loamhoof
8个回答

17
你正在使用 ^ 作为分隔符?你可能想要使用更像这样的东西:
'/^[a-z]{6}[0-9a-z]{2}([0-9a-z]{3})?\z/i'

使用PCRE函数时,需要将模式括在定界符中。定界符可以是任何非字母数字、非反斜杠、非空格字符。使用“^”作为定界符不应该有问题。 - Loamhoof
@Loamhoof,^^不起作用,你需要在这种情况下转义锚点,例如^\^,但我不确定这是否会为您提供PHP中字符的字面意义或元意义。在这种情况下,最好使用^\A - Qtax
是的,你说得对。无论如何,我们都必须等待OP更新。 - Loamhoof
提供无效和有效的示例。 - Sangoku
5
PHP 代码片段 $result_bic = (bool) ( preg_match('/^[a-z]{6}[0-9a-z]{2}([0-9a-z]{3})?\z/i', $bic) == 1 ); 的翻译如下:将变量 $bic 与正则表达式进行匹配,如果匹配成功则返回 true,否则返回 false。正则表达式的含义是以 6 个小写字母开头,后面跟着两个数字或小写字母,最后跟着三个数字或小写字母(可选),并且不区分大小写。 - Jaro
显示剩余4条评论

9

结构

最新版本为ISO 9362:2009(日期为2009-10-01)。SWIFT代码由8或11个字符组成:

4个字母:机构代码或银行代码。

2个字母:ISO 3166-1 alpha-2国家代码。

2个字母或数字:地点代码。

如果第二个字符是“0”,则通常是用于测试网络的BIC,而不是在实际网络中使用的BIC。如果第二个字符是“1”,则表示该参与者是SWIFT网络中的被动参与者。如果第二个字符是“2”,则通常表示反向结算的BIC,其中收件人支付信息费用,而不是更常见的发送方支付信息费用的模式。

3个字母或数字:分行代码,可选('XXX'表示主办公室)。

(http://en.wikipedia.org/wiki/ISO_9362)

(德语维基中定义不同http://de.wikipedia.org/wiki/ISO_9362

2个字母或数字:位置代码 第一个字符不能是数字“0”或“1”。 字母“O”不允许作为第二个字符。 (此定义的正则表达式:[2-9a-z] [0-9a-np-z])

'/^[a-z]{6}[2-9a-z][0-9a-np-z]([a-z0-9]{3}|x{3})?$/i'

3
提供一个有关您正则表达式中各个部分如何与规范相关的详细解释会很有用。 - forivall
3
德语维基百科也指出,除非是 XXX,否则可选的分支名称不能以“X”开头。 此时正则表达式应为'/^[A-Z]{6}[2-9A-Z][0-9A-NP-Z](XXX|[0-9A-WYZ][0-9A-Z]{2})?$/i' - chiborg

6
这是用于验证BIC的官方SEPA模式。
[A-Z]{6,6}[A-Z2-9][A-NP-Z0-9]([A-Z0-9]{3,3}){0,1}

7
你是从哪里找到的? - Us3rAIpha8rav0
不建议匹配像“SCHEDULE”和“Websense”这样的单词。@serraine的答案至少是准确的,即使效率不高。 - MattGarnett

2
我认为这个可以做:
/^[a-z0-9]{4}[a-z]{2}\d{2}([a-z0-9]{3})?$/

那就是:
  1. 字符串开始,^
  2. 四个字母数字字符,[a-z0-9]{4}
  3. 两个数字,\d{2}
  4. 三个可选(?后缀)的字母数字字符,([a-z0-9]{3})?
  5. 字符串结尾,$
你可以在这里看到它的运作并测试它(我使用了你的样本)。 无论如何,根据你所报告的规则,OPSKATWW不应该是一个有效的BIC,因为在前6个字母后面没有数字。

我需要使用z/i来确保它不区分大小写。 \d{2} 部分很好。会记下来的。 /d 表示十进制。不错。 - Sangoku
抱歉,我的意思是 /^[a-z0-9]{4}[a-z]{2}\d{2}([a-z0-9]{3})?$/i。这里的 z 是什么意思?无论如何,在对其进行正则表达式测试之前,您也可以执行 $bic=strtolower($bic) - Paolo Stefan

1

最新的ISO 9362:2022(E)允许以下字符串作为BIC:

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

注意:只允许使用大写字母;所以不要忽略大小写。

如果有需要,可以根据国家代码列表进行检查:

^[A-Z0-9]{4}(?:AD|AE|AF|AG|AI|AL|AM|AO|AQ|AR|AS|AT|AU|AW|AX|AZ|BA|BB|BD|BE|BF|BG|BH|BI|BJ|BL|BM|BN|BO|BQ|BR|BS|BT|BV|BW|BY|BZ|CA|CC|CD|CF|CG|CH|CI|CK|CL|CM|CN|CO|CR|CU|CV|CW|CX|CY|CZ|DE|DJ|DK|DM|DO|DZ|EC|EE|EG|EH|ER|ES|ET|FI|FJ|FK|FM|FO|FR|GA|GB|GD|GE|GF|GG|GH|GI|GL|GM|GN|GP|GQ|GR|GS|GT|GU|GW|GY|HK|HM|HN|HR|HT|HU|ID|IE|IL|IM|IN|IO|IQ|IR|IS|IT|JE|JM|JO|JP|KE|KG|KH|KI|KM|KN|KP|KR|KW|KY|KZ|LA|LB|LC|LI|LK|LR|LS|LT|LU|LV|LY|MA|MC|MD|ME|MF|MG|MH|MK|ML|MM|MN|MO|MP|MQ|MR|MS|MT|MU|MV|MW|MX|MY|MZ|NA|NC|NE|NF|NG|NI|NL|NO|NP|NR|NU|NZ|OM|PA|PE|PF|PG|PH|PK|PL|PM|PN|PR|PS|PT|PW|PY|QA|RE|RO|RS|RU|RW|SA|SB|SC|SD|SE|SG|SH|SI|SJ|SK|SL|SM|SN|SO|SR|SS|ST|SV|SX|SY|SZ|TC|TD|TF|TG|TH|TJ|TK|TL|TM|TN|TO|TR|TT|TV|TW|TZ|UA|UG|UM|US|UY|UZ|VA|VC|VE|VG|VI|VN|VU|WF|WS|YE|YT|ZA|ZM|ZW)[A-Z0-9]{2}(?:[A-Z0-9]{3})?$

请谨记serraine所提到的性能问题。
#FYI 这里可以找到国家代码列表:https://www.iso.org/obp/ui

1
echo preg_match('/^[A-Z]{4}(AC|AD|AE|AF|AG|AI|AL|AM|AN|AO|AQ|AR|AS|AT|AU|AW|AX|AZ|BA|BB|BD|BE|BF|BG|BH|BI|BJ|BL|BM|BN|BO|BQ|BR|BS|BT|BV|BW|BY|BZ|CA|CC|CD|CE|CF|CG|CH|CI|CK|CL|CM|CN|CO|CP|CR|CS|CU|CV|CW|CX|CY|CZ|DD|DE|DG|DJ|DK|DM|DO|DZ|EA|EC|EE|EG|EH|ER|ES|ET|EU|FI|FJ|FK|FM|FO|FR|FX|GA|GB|GD|GE|GF|GG|GH|GI|GL|GM|GN|GP|GQ|GR|GS|GT|GU|GW|GY|HK|HM|HN|HR|HT|HU|IC|ID|IE|IL|IM|IN|IO|IQ|IR|IS|IT|JE|JM|JO|JP|KE|KG|KH|KI|KM|KN|KP|KR|KW|KY|KZ|LA|LB|LC|LI|LK|LR|LS|LT|LU|LV|LY|MA|MC|MD|ME|MF|MG|MH|MK|ML|MM|MN|MO|MP|MQ|MR|MS|MT|MU|MV|MW|MX|MY|MZ|NA|NC|NE|NF|NG|NI|NL|NO|NP|NR|NT|NU|NZ|OM|PA|PE|PF|PG|PH|PK|PL|PM|PN|PR|PS|PT|PW|PY|QA|RE|RO|RS|RU|RW|SA|SB|SC|SD|SE|SF|SG|SH|SI|SJ|SK|SL|SM|SN|SO|SR|SS|ST|SU|SV|SX|SY|SZ|TA|TC|TD|TF|TG|TH|TJ|TK|TL|TM|TN|TO|TP|TR|TT|TV|TW|TZ|UA|UG|UK|UM|US|UY|UZ|VA|VC|VE|VG|VI|VN|VU|WF|WS|XK|YE|YT|ZA|ZM|ZR|ZW)[2-9A-Z][0-9A-NP-Z]([A-Z0-9]{3}|x{3})?$/',$val);

1

我不建议使用这个,因为它性能不佳,但如果有人需要根据ISO-3366-1国家代码验证IBANS:

/^[A-Z]{4}(AC|AD|AE|AF|AG|AI|AL|AM|AN|AO|AQ|AR|AS|AT|AU|AW|AX|AZ|BA|BB|BD|BE|BF|BG|BH|BI|BJ|BL|BM|BN|BO|BQ|BR|BS|BT|BV|BW|BY|BZ|CA|CC|CD|CE|CF|CG|CH|CI|CK|CL|CM|CN|CO|CP|CR|CS|CU|CV|CW|CX|CY|CZ|DD|DE|DG|DJ|DK|DM|DO|DZ|EA|EC|EE|EG|EH|ER|ES|ET|EU|FI|FJ|FK|FM|FO|FR|FX|GA|GB|GD|GE|GF|GG|GH|GI|GL|GM|GN|GP|GQ|GR|GS|GT|GU|GW|GY|HK|HM|HN|HR|HT|HU|IC|ID|IE|IL|IM|IN|IO|IQ|IR|IS|IT|JE|JM|JO|JP|KE|KG|KH|KI|KM|KN|KP|KR|KW|KY|KZ|LA|LB|LC|LI|LK|LR|LS|LT|LU|LV|LY|MA|MC|MD|ME|MF|MG|MH|MK|ML|MM|MN|MO|MP|MQ|MR|MS|MT|MU|MV|MW|MX|MY|MZ|NA|NC|NE|NF|NG|NI|NL|NO|NP|NR|NT|NU|NZ|OM|PA|PE|PF|PG|PH|PK|PL|PM|PN|PR|PS|PT|PW|PY|QA|RE|RO|RS|RU|RW|SA|SB|SC|SD|SE|SF|SG|SH|SI|SJ|SK|SL|SM|SN|SO|SR|SS|ST|SU|SV|SX|SY|SZ|TA|TC|TD|TF|TG|TH|TJ|TK|TL |TM|TN|TO|TP|TR|TT|TV|TW|TZ|UA|UG|UK|UM|US|UY|UZ|VA|VC|VE|VG|VI|VN|VU|WF|WS|XK|YE|YT|ZA|ZM|ZR|ZW)[2-9A-Z][0-9A-NP-Z](XXX|[0-9A-WYZ][0-9A-Z]{2})?$/i

此外,这是内容验证而不仅仅是格式验证。但它将为您节省一些代码 :)

你正在回答什么问题? - Toto

-3

好的。对于所有遇到这种问题的人,正确的正则表达式是:

/^[0-9a-z]{4}[a-z]{2}[0-9a-z]{2}([0-9a-z]{3})?\z/i

感谢 @Qtax 提供它。我只是稍微改进了一下。

修改的地方是,我将前4个字母可以是字母数字混合的形式,但后面的2个字母必须代表一个国际代码。这就是为什么只能使用字母。我还与实际使用代码的用户进行了检查。他们可以在前4个位置上有数字值。

编辑:

我错了。前4个字母只能是字母。我曾经依赖来自Reifeisen银行的员工的说法,他们正在讨论标准。结果他认为银行的编号从他们内部的某个系统中获得的号码可能是有效的代码。事实证明这不是正确的情况。

因此,正确的语法是

/^{6}[a-z]{2}[0-9a-z]{2}([0-9a-z]{3})?\z/i

会标记正确答案。感谢您指出。


1
为什么在前四个字符后面添加数字?这不在你的问题描述或链接的规格说明中。 - Qtax
这是有关国家和数字的代码。相信我,这个没问题 :) - Sangoku
对于所有使用负4字母进行评分的人,某些国家的字母可以包含数字,但必须以2位数字结尾,否则银行的检查将失败。在此调用之后,我直接调用银行API。 - Sangoku
Sangoki最后一个正则表达式正确。BIC的前四个字符必须是字母,而不是数字。我认为正确的应该是:/^[a-z]{4}[a-z]{2}[0-9a-z]{2}([0-9a-z]{3})?\z/i 或者 - 为了缩短长度 /^[a-z]{6}[0-9a-z]{2}([0-9a-z]{3})?\z/i - Armin Hierstetter
1
不再是这样了。前四个字符可以是数字。请参阅https://dev59.com/u2Uo5IYBdhLWcg3wmAWi#73048163。 - VisioN

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