c#正则表达式,用于特定区域之外的匹配

本文关键字:区域 正则表达式 用于 | 更新日期: 2023-09-27 17:49:22

我必须找到某个字符串(needle)在另一个字符串(haystack)中的出现,而不是出现在特定的"花括号"之间。

例如考虑这个干草堆:"开始某件事,结束另一件事,开始另一件事,结束更多的事情。"这根针:"一些"加上大括号"BEGIN"answers"END"

我想找到所有不在括号之间的针。(有两种匹配:"some"后面跟"other"answers"some"后面跟"more")

我想我可以解决这个问题与负向前看/向后看的Regex,但如何?

我试过了

(?<!(BEGIN))some(?!(END))

这给了我4个匹配(显然因为没有"some"直接包含在"BEGIN"answers"END"之间)

我也试过

(?<!(BEGIN.*))some(?!(.*END))

但是这没有给我任何匹配(显然是因为每个指针前面都有一个"BEGIN")

不,我卡住了。

下面是我使用的最新c#代码:

string input = "BEGIN something END some other thing BEGIN something else END yet some more things.";
global::System.Text.RegularExpressions.Regex re = new Regex(@"(?<!(BEGIN.*))some(?!(.*END))");
global::System.Text.RegularExpressions.MatchCollection matches = re.Matches(input);
global::NUnit.Framework.Assert.AreEqual(2, matches.Count);

c#正则表达式,用于特定区域之外的匹配

像这样的东西对你有用吗?

(?:^|END)((?!BEGIN).*?)(some)(.*?)(?:BEGIN|$)

这似乎匹配您的文本,因为我测试使用RegExDesigner.NET

一个简单的选择是跳过您不想匹配的部分,只捕获您需要的针:

MatchCollection matches = Regex.Matches(input, "BEGIN.*?END|(?<Needle>some)");

你会得到两个"一些"你所追求的成功的"针"组从所有的比赛:

IEnumerable<Group> needles = matches.Cast<Match>()
                                    .Select(m => m.Groups["Needle"])
                                    .Where(g => g.Success);

您可以尝试在出现BEGIN或END时分割字符串,以便您可以确保在您应用正则表达式的字符串中只有一个BEGIN和一个END。此外,如果您正在寻找在BEGIN/END大括号之外出现的SOME,那么我认为您需要向后查找END并向前查找BEGIN(正向前/向后),与您所拥有的相反。

如果您只是处理整个干草堆而忽略大括号之间的干草会怎么样(我是否将比喻推得太远了?)

例如,查看所有标记(或字符,如果您需要进入该级别)并查找大括号。找到开始括号后,循环直到找到结束括号。在这一点上,你开始寻找你的针,直到你找到另一个开口支架。它的代码比Regex多一点,但可能更容易阅读,更容易排除故障。