RegEx的性能和可读性使用积极向前看

时间:2015-10-07 07:09:24

标签: c# regex

我正在使用C#中的正则表达式验证以下字符串:

  

[/ 1/2 /]
  [/ 1/2 /]; [/ 3/4/5 /]
  [/ 1 /333分之22/]; [/ 1 /]; [/ 9999 /

基本上它是由分号(但不在末尾)分隔的一个或多个方括号组。每个组由一个或多个由斜杠分隔的数字组成。没有其他角色可以使用。

这是两种选择:

^(\[\/(\d+\/)+\](;(?=\[)|$))+$

^(\[\/(\d+\/)+\];)*(\[\/(\d+\/)+\])$

第一个版本使用正向前看,第二个版本复制模式的一部分。

RegEx-es似乎都没问题,做他们应该做的事情,并且阅读起来不是很好。 ;)

是否有人想要更好,更快,更易读的解决方案?当我在regex101玩游戏时,我意识到第二个版本使用了更多步骤,为什么?

与此同时,我意识到计算C#-RegEx中使用的步骤会很好。有没有办法实现这个目标?

2 个答案:

答案 0 :(得分:2)

您可以使用1个正则表达式来验证所有这些字符串:

^\[/(\d+/)+\](?:;\[/(\d+/)+\])*$

请参阅regex demo

为了便于阅读,请使用VERBOSE标记(内联(?x)RegexOptions.IgnorePatternWhitespace):

var rx = @"(?x)^               # Start of string
           \[/             # Literal `[/`
           (\d+/)+         # 1 or more sequences of 1 or more digits followed by `/`
           \]              # Closing `]`
           (?:             # A non-capturing group start
             ;             # a semi-colon delimiter
              \[/(\d+/)+\] # Same as the first part of the regex
           )*              # 0 or more occurrences
           $               # End of string
";

要测试.NET正则表达式性能(而不是步骤数),您可以使用regexhero.net服务。使用上面的3个示例字符串,我的正则表达式显示每秒217K次迭代速度,这比任何一个正则表达式都要多。

答案 1 :(得分:1)

您建议的两个选项没有什么特别的错误。它们并不像正则表达式那样复杂,只要你在代码中添加适当的注释,它们应该是可以理解的。

一般来说,我认为最好避免使用环视,除非它们是必要的或大大简化了正则表达式 - 它们使得更难以弄清楚发生了什么,因为它们添加了一个非线性元素逻辑。

正则表达式的相对性能这个简单并不值得担心,除非您执行大量操作或发现代码存在性能问题。不过,理解不同模式的相对表现可能具有指导意义。