我正试图编写一个正则表达式来匹配正则数字(1,2,42…(和罗马数字(X,VII…(。
但我现在写的是:
b((?=[MDCLXVI])M{0,3}(C[MD]|D?C{0,3})(X[CL]|L?X{0,3})(I[XV]|V?I{0,3}))b|bd+b
匹配的数量超出预期。它有9场比赛,而我预计只有4:
- XII
- VII
- 2
- 12
如何修复?
在正则表达式中不需要任何前瞻性。
您的正则表达式可以简化并重构为:
/
b
(?:
[MDCLXVI]M{0,3}C[MD]
|
D?C{0,3}X[CL]
|
L?X{0,3}I[XV]
|
[XV]I{0,3}
|
I{1.3}
|
d+
)
b
/gix
更新RegEx演示
请注意,我在regex中使用了x
(扩展模式(,因此regex将忽略所有空格,这允许您在多个替换项之间进行适当的缩进,以使regex更具可读性。我不知道罗马数字的所有排列,所以我建议你重新检查每一个排列。
原因是零宽度匹配仅与单词边界模式匹配的可能性(即b(?=[MDCLXVI])b
在任何以罗马数字字母开头的单词之前匹配(。
你需要精确的单词边界,使前面的一个只匹配单词字符之前,最后一个只在单词字符之后匹配:
(?<!w)(?:(?=[MDCLXVI])M{0,3}(?:C[MD]|D?C{0,3})(?:X[CL]|L?X{0,3})(?:I[XV]|V?I{0,3})|d+)(?!w)
请参阅regex演示。
这里,如果在当前位置的左处立即存在单词char,则(?<!w)
充当匹配失败的单词边界,并且如果在当前地点的右附近立即存在单词char,则(?!w)
充当匹配失败。