如何优化此正则表达式以获得更好的性能?
How can I optimize this regex to get better performance?
我正在尝试优化我的一个 .NET 应用程序的正则表达式。
正则表达式:(?<!WordA\s(?:WordB\s)?)(WordB\s)?WordC
逻辑:
- 查找匹配的 WordC
- 加入 WordB 进行匹配(如果在 WordC 之前出现)
- 如果 WordC(即使前面有 WordB)前面有 WordA,则不匹配任何内容
应该匹配:
- WordC
- WordB WordC
不应该匹配:
- 字A字C
- WordA WordB WordC
该表达式有效,但如您所见,WordB 在表达式中出现了两次,因此我试图删除其中一个以获得更好的性能。
注意:“词”其实是复杂的表达方式。
有什么办法吗?
“优化”(?<!WordA\s(?:WordB\s)?)(WordB\s)?WordC
正则表达式(即 (?<!WordA\s)WordC
和 (?<!WordA\s)WordB\sWordC
的组合)的问题是 WordB
和 WordC
是以空格分隔,一旦 WordB WordC
以 WordA
开头,负向后视不会使正则表达式引擎跳过匹配的短语,它只会跳过失败的位置,因此 WordC
将如果您只使用 (?<!WordA\s)(WordB\s)?WordC
,则匹配。后视必须限制 WordB\sWordC
和 WordC
这就是为什么你必须在后视模式中重复可选的 WordB
,就像你在上面显示的两个“解构”模式中使用它一样.
因此,使用纯字符串正则表达式,别无他法。
涉及一些代码更改的解决方法可能类似于
var rx = @"(WordA\s)?(?:WordB\s)?WordC";
var strings = new List<String> {"WordC", "WordB WordC", "WordA WordC", "WordA WordB WordC"};
foreach (var s in strings)
{
var m = Regex.Match(s, rx);
Console.WriteLine("{0}: {1}", s, (m.Groups[1].Success ? "NO MATCH" : m.Value));
}
// => WordC: WordC
// => WordB WordC: WordB WordC
// => WordA WordC: NO MATCH
// => WordA WordB WordC: NO MATCH
参见C# demo。
在 (WordA\s)?(?:WordB\s)?WordC
正则表达式中,(WordA\s)?
捕获带有空格的 WordA
被捕获到第 1 组,如果它匹配,我们知道我们需要丢弃匹配。如果第1组.Success
值为false,则表示匹配有效。
我正在尝试优化我的一个 .NET 应用程序的正则表达式。
正则表达式:(?<!WordA\s(?:WordB\s)?)(WordB\s)?WordC
逻辑:
- 查找匹配的 WordC
- 加入 WordB 进行匹配(如果在 WordC 之前出现)
- 如果 WordC(即使前面有 WordB)前面有 WordA,则不匹配任何内容
应该匹配:
- WordC
- WordB WordC
不应该匹配:
- 字A字C
- WordA WordB WordC
该表达式有效,但如您所见,WordB 在表达式中出现了两次,因此我试图删除其中一个以获得更好的性能。
注意:“词”其实是复杂的表达方式。
有什么办法吗?
“优化”(?<!WordA\s(?:WordB\s)?)(WordB\s)?WordC
正则表达式(即 (?<!WordA\s)WordC
和 (?<!WordA\s)WordB\sWordC
的组合)的问题是 WordB
和 WordC
是以空格分隔,一旦 WordB WordC
以 WordA
开头,负向后视不会使正则表达式引擎跳过匹配的短语,它只会跳过失败的位置,因此 WordC
将如果您只使用 (?<!WordA\s)(WordB\s)?WordC
,则匹配。后视必须限制 WordB\sWordC
和 WordC
这就是为什么你必须在后视模式中重复可选的 WordB
,就像你在上面显示的两个“解构”模式中使用它一样.
因此,使用纯字符串正则表达式,别无他法。
涉及一些代码更改的解决方法可能类似于
var rx = @"(WordA\s)?(?:WordB\s)?WordC";
var strings = new List<String> {"WordC", "WordB WordC", "WordA WordC", "WordA WordB WordC"};
foreach (var s in strings)
{
var m = Regex.Match(s, rx);
Console.WriteLine("{0}: {1}", s, (m.Groups[1].Success ? "NO MATCH" : m.Value));
}
// => WordC: WordC
// => WordB WordC: WordB WordC
// => WordA WordC: NO MATCH
// => WordA WordB WordC: NO MATCH
参见C# demo。
在 (WordA\s)?(?:WordB\s)?WordC
正则表达式中,(WordA\s)?
捕获带有空格的 WordA
被捕获到第 1 组,如果它匹配,我们知道我们需要丢弃匹配。如果第1组.Success
值为false,则表示匹配有效。