2011-04-08 142 views
2

我必须在另一个字符串(干草堆)内找到特定“大括号”之间不发生的特定字符串(针)的出现。C#正则表达式匹配特定区域外的匹配

例如,考虑这个干草堆: “开始的东西结束一些其他的事情开始的东西结束还有更多的东西。” 而这种针: “一些” 随着我想找到不花括号之间的所有针在大括号“BEGIN”和“END”

。 (有两个匹配:“一些”后面跟着“其他”和“一些”后面跟着“更多”)

我想我可以使用带有负向望远镜/ lookbehind的正则表达式解决这个问题,但是怎么做?

我已经试过

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

这给了我4场比赛(显然是因为没有 “一定” 是直接封闭之间的 “开始” 和 “结束”)

我也试过

(?<!(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); 
+0

除了使用正则表达式之外,您是如何尝试其他解决方案的? – jfs 2011-04-08 15:49:37

回答

1

将这样的事情对你的工作:

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

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

+0

上面的表达它!非常感谢。我只需要得到Group [2] .Value而不是Group [0] .Value,但没关系。也感谢提及RegExDesigner。我以前没听说过。 – miasbeck 2011-04-08 16:27:23

+0

我认为这个表达式不起作用,如果你在同一个'end'和'begin'之间有多个'some'' - “有些END会开始一些” – Kobi 2011-04-08 16:43:01

0

您可以尝试在BEGIN和END的出现分裂的字符串,这样就可以确保只有一个BEGIN和字符串中的一端,你将你的正则表达式应用于。此外,如果您正在寻找BEGIN/END括号外的某些事件,那么我认为您应该向后看END并向前看(BEGIN)(正面向前/向后),与您所拥有的相反。

希望这会有所帮助。

0

如果你只是处理整个草垛而忽略干草是在括号(是我推的比喻太远?)

之间。例如,通过所有的标记看(或字符,如果你需要去那个级别)并寻找你的大括号。当找到开头的时候,你会循环直到找到右大括号。此时,你开始寻找你的针,直到你找到另一个开口支撑。它的代码比正则表达式多一点,但可能更易读,更容易排除故障。

1

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

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

你会得到两个“一定”是你的就是后在所有匹配中取得成功的“Needle”组:

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

+1,这很聪明。你测试过了吗?我可以告诉你的想法是,交替运算符('|')会使任何匹配'BEGIN。*?END'的东西与捕获组短路,但我并不认为交替是正则表达式中的短路。 – 2011-04-08 20:04:25

+0

更新:它确实有效。 http://rubular.com/r/6mKSumbyuF。我一定会记住这个诀窍。 – 2011-04-08 20:08:00

+0

@Justin - 谢谢!这不是关于短路,而是关于匹配引擎的工作方式 - 如果它找到了匹配“开始 - 结束”模块,则它不会搜索并捕获“some”。我有一些解释[这里](http://stackoverflow.com/questions/5153980/#5154081),[这里](http://stackoverflow.com/questions/4383068/4384901#4384901)和[这里] (http://stackoverflow.com/questions/5283269/#5288185)。 – Kobi 2011-04-08 21:54:24