我有以下正则表达式:
(\d+\s+[-]\s+.*?(?=\s+-)|\d+\s+[-].*)
Run Code Online (Sandbox Code Playgroud)
正则表达式将使用此文本
"Option 01 - Random phrase - Top Menu",
"Option 02 - Another Random Phrase - Su Menu",
"Option 03 - More 01 Phrase - Menu",
"Option 04 - More Phrase -",
"Option 05 - Simple Phrase"
Run Code Online (Sandbox Code Playgroud)
要这样住
01 - Random phrase ",
02 - Another Random Phrase ",
03 - More 01 Phrase ",
04 - More Phrase ",
05 - Simple Phrase ",
Run Code Online (Sandbox Code Playgroud)
此Regex的功能是在开头加上破折号,然后在最后一个破折号前加上数字。例如:
当最终没有踪迹时,基本上会发生这种情况:
但是,在regex101.com上调试此正则表达式会导致您需要63到122个步骤。也就是说,此正则表达式非常慢。
在批评这个问题之前,我已经阅读了正则表达式的所有文档,我想让您知道我所指的是特定术语..一个需要解决的问题。毕竟,这不是网站吗?
告诉我,我该如何解决此正则表达式的缓慢性?
您不必担心在regex101.com上看到的步骤,因为C#regex库非常可靠。如果您(?s)a.*?b使用很长的字符串测试像regex101 这样的简单正则表达式,它将报告灾难性的回溯,而在C#代码中则可以正常工作。
有一种方法可以改进您的模式,因为它有一些冗余:请参见重复\d+\s+[-]模式。
所有你需要的是
\d+\s+-.*?(?=\s+-|$)
Run Code Online (Sandbox Code Playgroud)
请参阅regex101和RegexStorm上的regex演示。
如果.*?(?=\s+-)仅在后面有空格时才匹配-,请使用
\d+\s+-(?:\s.*?(?=\s+-)|.+)
Run Code Online (Sandbox Code Playgroud)
如果您想进一步优化它,则可能需要研究导致问题的展开原理。
\d+\s+-(?:\s+\S*(?:\s(?!\s*-)\S*)*|.+)
Run Code Online (Sandbox Code Playgroud)
请参阅此正则表达式演示(最少的步数)。
在这里,\S*(?:\s(?!\s*-)\S*)*是的等效项(几乎).*?(?=\s+-|$),但是效率更高,因为直至空白的块都以“批”进行匹配,仅当遇到空白时才进行连字符检查。
细节
\d+ -1个以上的数字\s+ -1+空格- -连字符.*?(?=\s+-|$)-直到第一次出现1+个空格和/ -或直到字符串末尾的任何0+个字符,尽可能少。(?:\s.*?(?=\s+-)|.+) -非捕获组:
\s.*?(?=\s+-) -空格,最多0个字符,最多1个空格, -| - 要么 .+ -字符串的其余部分。\S*(?:\s(?!\s*-)\S*)* :
\S* -0+个非空白字符(?:\s(?!\s*-)\S*)* -重复0次或以上
\s -空格(?!\s*-) -后面没有0+空格, -\S* -0+个非空白字符