我正在尝试匹配英国银行的排序代码(没有复杂的,只有三对数字,可选择用连字符分隔)。我想我可以尝试匹配第一个连字符,然后使用反向引用来检查我匹配的值是否正在使用连字符。
/^\d{2}(-)?\d{2}\1\d{2}$/
哪个应匹配
12-34-56
123456
但不是反对
12-3456
1234-56
这很好,并且在JavaScript中运行良好。
当我使用PCRE引擎(例如PHP)时,正则表达式与我期望的不匹配。我使用了不同的正则表达式来避免这种情况,但我仍然想知道发生了什么?
我可以在(*SKIP)(*FAIL)
的行中使用一些内部暗魔法来使用可选的反向引用吗?
答案 0 :(得分:2)
您可以更改正则表达式以匹配它:
^\d{2}(-|)\d{2}\1\d{2}$
将(-)?
更改为(-|)
可确保我们在组#1中捕获连字符或空字符串。
<强>代码:强>
新RegEx:
preg_match('/^\d{2}(-|)\d{2}\1\d{2}$/', '123456', $m);
print_r($m);
Array
(
[0] => 123456
[1] =>
)
较旧的正则表达式:
preg_match('/^\d{2}(-)?\d{2}\1\d{2}$/', '123456', $m);
print_r($m);
Array
(
)
答案 1 :(得分:2)
JavaScript遵循ECMA标准规范。
根据官方的ECMA标准,对非参与捕获组的反向引用必须成功地匹配任何内容,就像对没有捕获任何内容的参与组的反向引用一样。 (source)
此处,在/^\d{2}(-)?\d{2}\1\d{2}$/
中,我们有一个 可选 捕获组,可以匹配连字符。 JavaScript正则表达式引擎&#34;消费&#34;可选组中的空文本,以便以后通过反向引用访问它们。这个问题与Backreferences to Failed Groups密切相关。例如。 ((q)?b\2)
将匹配JavaScript中的b
,但它在PCRE中不匹配。
所以,一个出路是使用强制性捕获组,并使用空替代(demo):
^\d{2}(-|)\d{2}\1\d{2}$
^^
此外,您可以将?
量词移动到连字符本身(demo):
^\d{2}(-?)\d{2}\1\d{2}$