正则表达式匹配排序代码

Regex matching sortcode

我正在尝试匹配英国银行分类代码(没有什么复杂的,只有三对数字,可以选择用连字符分隔)。我想我可以尝试匹配第一个连字符,然后使用反向引用来检查我匹配的值是否完全使用连字符。

/^\d{2}(-)?\d{2}\d{2}$/

哪个应该匹配

12-34-56
123456

但不反对

12-3456
1234-56

这很好并且工作正常 — 在 JavaScript.

当我使用 PCRE 引擎(例如 PHP)时,正则表达式与我预期的不匹配。我使用了不同的正则表达式来避免这种情况,但我仍然想知道发生了什么?

我可以按照 (*SKIP)(*FAIL) 使用一些内部黑魔法来使用可选的反向引用吗?

您可以更改正则表达式以匹配它:

^\d{2}(-|)\d{2}\d{2}$

RegEx Demo

(-)? 更改为 (-|) 可确保我们捕获组 #1 中的连字符或空字符串。

代码:

新正则表达式:

preg_match('/^\d{2}(-|)\d{2}\d{2}$/', '123456', $m);
print_r($m);
Array
(
    [0] => 123456
    [1] =>
)

旧的正则表达式:

preg_match('/^\d{2}(-)?\d{2}\d{2}$/', '123456', $m);
print_r($m);
Array
(
)

JavaScript 遵循 ECMA 标准规范。

According to the official ECMA standard, a backreference to a non-participating capturing group must successfully match nothing just like a backreference to a participating group that captured nothing does. (source)

这里,在 /^\d{2}(-)?\d{2}\d{2}$/ 中,我们有一个 可选 捕获组 可以匹配连字符。 JavaScript 正则表达式引擎 "consumes" 可选组中的空文本,以便以后可以通过反向引用访问它们。这个问题与Backreferences to Failed Groups息息相关。例如。 ((q)?b) 将匹配 JavaScript 中的 b,但不会匹配 PCRE。

因此,解决方法是使用 强制性 捕获组和空替代项 (demo):

^\d{2}(-|)\d{2}\d{2}$
        ^^

此外,您可以将 ? 量词移动到连字符本身 (demo):

^\d{2}(-?)\d{2}\d{2}$