匹配数字的正则表达式(包括正则表达式和罗马表达式)



我正试图编写一个正则表达式来匹配正则数字(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)充当匹配失败。

最新更新