不要在 c# Regex 中使用捕获组

Don't use capturing groups in c# Regex

我正在 Visual Studio 2013 年使用 C#

编写正则表达式

我有以下场景:

Match match = Regex.Match("%%Text%%More text%%More more text", "(?<!^)%%[^%]+%%");

但我的问题是我不想捕获组。原因是捕获组 match.Value 包含 %%More text%% 而我的想法是直接在 match.Value 上获取字符串:More text

要获取的字符串总是在%%的第二组和第三组之间 另一种方法是字符串将始终在第四个和第五个 %

之间

我试过了:

Regex.Match("%%Text%%More text%%More more text", "(?:(?<!^)%%[^%]+%%)");

但运气不好。

我想使用 match.Value 因为我所有的正则表达式都在数据库 table.

有没有办法 "transform" 将正则表达式转换为不使用捕获组的 match.value 所需字符串?​​

如果您确定双 %% 中没有 %,您可以像这样使用环视:

(?<=^%%[^%]*%%)[^%]+(?=%%)
^^^^^^^^^^^^^^      ^^^^^

如果您有单 % 分隔的字符串(如 %text1%text2%text3%text4%text5%text6,请参阅 demo):

(?<=^%[^%]*%)[^%]+(?=%)

regex demo

如果在第 4 和第 5 之间:

(?<=^%%(?:[^%]*%%){3})[^%]+(?=%%)
^^^^^^^^^^^^^^^^^^^^^^     ^^^^^^

对于单 % 分隔字符串(参见 demo):

(?<=^%(?:[^%]*%){3})[^%]+(?=%)

参见 another demo

这两个正则表达式都包含一个可变宽度的后视和相同的前视,以限制 1 个或多个除 % 之外的字符出现的上下文。

(?<=^%%[^%]*%%) 确保 %%[something_other_then_%]%% 紧跟在字符串开头之后,(?<=^%%(?:[^%]*%%){3}) 匹配字符串开头之后的 %%[substring_not_having_%]%%[substring_not_having_%]%%[substring_not_having_%]%%

如果双 %% 中可以有单个 % 符号,您可以使用展开循环正则表达式(参见 demo):

(?<=^%%(?:[^%]*(?:%(?!%)[^%]*)*%%){3})[^%]*(?:%(?!%)[^%]*)*(?=%%)

(?<=^%%(?:.*?%%){3}).*?(?=%%) 匹配的内容相同。对于短字符串,基于 .*? 的解决方案应该工作得更快。对于非常长的输入文本,请使用展开版本。