背景
我有一个场景,我必须反复在文本中反复找到某些单词。 我目前使用了一系列常规表达式,格式如下......
"((^)|(\W))(?<c>Word1)((\W)|($))"
"((^)|(\W))(?<c>NextWord)((\W)|($))"
"((^)|(\W))(?<c>AnotherWord)((\W)|($))"
...
这个Regex对象列表是用一大块数据循环的,并且匹配被拉出(一个循环用于一个regex.matches(数据)调用)
我尽我所能来优化它们,例如事先编译它们。
然而,列表越来越长,我决定开始制作更大的编译正则表达式来优化过程。比如......
"((^)|(\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%)。当你进入多个表达式时,这绝对是要记住的东西。非常高兴。
答案 0 :(得分:1)
使用\b
符号。这匹配单词/非单词边界。
\b(?((Word1)|(NextWord)|(AnotherWord)))\b
答案 1 :(得分:1)
您可能希望使用边界检查或前瞻/后瞻,以便匹配不消耗空白但检查它。
像这样:
Pattern = @"\b(Word1|NextWord|AnotherWord)\b"
或者使用lookbehind和lookahead:
Pattern = @"(?<=\W|^)(Word1|NextWord|AnotherWord)(?=\W|$)"