【问题标题】:Optimization of multiple expressions to one将多个表达式优化为一个
【发布时间】:2012-10-17 01:36:42
【问题描述】:

背景

我有一个场景,我必须一遍又一遍地在文本中找到某些单词。 我目前使用了一系列像这样格式的正则表达式......

"((^)|(\W))(?<c>Word1)((\W)|($))"

"((^)|(\W))(?<c>NextWord)((\W)|($))"

"((^)|(\W))(?<c>AnotherWord)((\W)|($))"

...

这个 Regex 对象列表是用一大块数据循环的,并且匹配项被拉出(一个循环用于一个 regex.matches(data) 调用)

我已尽我所能优化它们,例如事先编译它们。

但是列表越来越长,我决定开始制作更大的编译正则表达式来优化流程。比如……

"((^)|(\W))(?<c>((Word1)|(NextWord)|(AnotherWord)))((\W)|($))"

这提供了巨大的速度改进,但是有一个副作用,我不知道如何纠正。

当单词并排出现在数据中时(例如空格分隔。例如“Word1 NextWord AnotherWord”),第二个单词在捕获中会丢失,因为“Word1”的正则表达式还包括尾随空格。 “NextWord”可能出现的匹配不再具有前导空格,因为它是上一个匹配的一部分。

问题

任何人都可以更改此正则表达式(.net 格式)

Pattern = "((^)|(\W))(?<c>((Word1)|(NextWord)|(AnotherWord)))((\W)|($))"

通过一次调用“.matches(data)”来捕获下面这个列表中的所有单词 在哪里

data = "Word1 NextWord AnotherWord" 

? (不牺牲效率增益)

结果

只是想我会提到这一点。在应用建议的答案/更正并向前看之后,我现在知道如何使用:),我刚刚修改的代码的速度提高了 347 倍(旧测试速度的 0.00347%)。当您遇到多个表达式时,这绝对是要记住的事情。很开心。

【问题讨论】:

标签: .net regex performance backreference


【解决方案1】:

您可能想要使用边界检查或前瞻/后瞻,以便匹配不会消耗空格而是检查它。

像这样:

Pattern = @"\b(Word1|NextWord|AnotherWord)\b"

或者使用后视和前瞻:

Pattern = @"(?<=\W|^)(Word1|NextWord|AnotherWord)(?=\W|$)"

【讨论】:

  • 你有“lookbehind”的简单例子吗?我有更多的匹配类型,边界这个词不适用,而且我一点也不熟悉。边界一词适用于本示例。谢谢。
  • @Lucero:对。那是为了问题,而不是答案。
  • @Lucero 非常感谢。你也是约翰,没有意识到标签/名称重叠的事情,这是有道理的。
【解决方案2】:

使用\b 符号。这匹配单词/非单词边界。

\b(?((Word1)|(NextWord)|(AnotherWord)))\b

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-27
    • 1970-01-01
    • 1970-01-01
    • 2011-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多