简化我的正则表达式(它在C#中有很多建议不起作用,我已经尝试过了)

时间:2016-09-06 16:09:49

标签: c# regex

任何人都可以简化我的正则表达式吗?我经过多次测试后设计了它并尝试了很多东西。请不要根据JS规则进行简化,他们似乎在不同。否则我会自己做的。

"^[M]{0,3}([C]{1}[M]{1}){0,1}[D]{0,3}([C]{1}[D]{1}){0,1}[C]{0,3}([X]{1}[C]{1}){0,1}[L]{0,3}([X]{1}[L]{1}){0,1}[X]{0,3}([I]{1}[X]{1}){0,1}[V]{0,3}([I]{1}[V]{1}){0,1}[I]{0,3}$"

所有带序列的字符都是强制性的。

添加一些规则。这个是根据我的要求为某些罗马数字系统...

通过将符号组合在一起并添加值来形成数字。例如,MMVI是1000 + 1000 + 5 + 1 = 2006.通常,符号按值的顺序放置,从最大值开始。如果较小的值位于较大的值之前,则较小的值将从较大的值中减去,并将结果添加到总计中。例如MCMXLIV = 1000 +(1000 - 100)+(50 - 10)+(5 - 1)= 1944。

符号" I"," X"," C"和" M"可以连续重复三次,但不能再重复。 (如果第三个和第四个用较小的值分隔,它们可能会出现四次,例如XXXIX。)" D"," L"和" V"永远不会重复。 " I"可以从" V"中删除和" X"只要。 " X"可以从" L"中删除和" C"只要。 " C"可以从" D"中删除和" M"只要。 " V"," L"和" D"永远不能减去。

只能从任何大值符号中减去一个小值符号。 用[16]阿拉伯数字写的数字可以分成数字。例如,1903由1,9,0和3组成。要写入罗马数字,应分别处理每个非零数字。在上面的例子中,1,000 = M,900 = CM,3 = III。因此,1903 = MCMIII。

2 个答案:

答案 0 :(得分:3)

几点:

  • 不需要只有一个项目的字符类,因此“[M]”可以替换为“M”(例如)
  • “{0,1}”始终可以替换为“?”不改变正则表达式的含义
  • 您永远不需要包含“{1}”,因为它不会添加任何其他约束
  • 对于长正则表达式,我建议使用字符串常量将正则表达式分解为逻辑“子组”,并使用它们“构建”正则表达式 - 它更容易阅读
  • 始终在正则表达式上方添加注释,解释其目的,并提供有效和无效输入的示例(除非它足够短以至于显而易见),否则将难以维护

我没有像我想的那样彻底地测试它(考虑到有效和无效字符串的一些例子,这样做会更容易)但是这里有一个例子:

"^M{0,3}(CM)?D{0,3}(CD)?C{0,3}(XC)?L{0,3}(XL)?X{0,3}(IX)?V{0,3}(IV)?I{0,3}$"

这将匹配字符串“MDCLXVI”,但不匹配“MMMMDCLXVI”。

话虽如此,我怀疑你原来的正则表达式并没有完全符合你的意图,所以这可能不仅仅是一个简化的问题。例如,您在帖子中声明“所有带序列的字符都是强制性的”,但现在没有需要特定的字符串序列;事实上,正则表达式甚至会匹配空字符串,我怀疑这不是你想要的。

答案 1 :(得分:0)

这个等式现在不能简化,因为我试图在C#正则表达式处理中验证字符串。我还尝试了很多其他方法,包括上面提供的建议。

现在关闭这个问题。