我必须在另一个字符串(haystack)中找到特定字符串(针)的出现,这些字符串在特定的“大括号”之间不会出现。
例如考虑这个大海捞针: “从某些事情开始,还有其他一些东西开始了,还有更多东西。” 而这针: “一些” 括号“BEGIN”和“END”
我想找到不在大括号之间的所有针。 (有两个匹配:“some”后跟“other”,“some”后跟“more”)
我想我可以使用具有负前瞻/后视的正则表达式来解决这个问题,但是怎么做?
我试过了
(?<!(BEGIN))some(?!(END))
给了我4个匹配(显然因为“BEGIN”和“END”之间没有“some”直接包含)
我也试过
(?<!(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 :(得分:1)
这样的事情对你有用:
(?:^|END)((?!BEGIN).*?)(some)(.*?)(?:BEGIN|$)
这似乎与您的文本相符,就像我使用RegExDesigner.NET测试一样。
答案 1 :(得分:1)
一个简单的选择是跳过你不想匹配的部分,只捕捉你需要的针:
MatchCollection matches = Regex.Matches(input, "BEGIN.*?END|(?<Needle>some)");
你可以通过在所有比赛中取得成功的“针”组来获得你所追求的两个“一些”:
IEnumerable<Group> needles = matches.Cast<Match>()
.Select(m => m.Groups["Needle"])
.Where(g => g.Success);
答案 2 :(得分:0)
您可以尝试在出现BEGIN或END时分割字符串,以便确保在您应用正则表达式的字符串中只有一个BEGIN和一个END。另外,如果你正在寻找BEGIN / END括号之外的某些事件,那么我认为你想要看看END的后面和BEGIN的前瞻(正面向前/后),与你所拥有的相反。
希望这有帮助。
答案 3 :(得分:0)
如果你只处理整个干草堆并忽略大括号之间的干草(我把这个比喻推得太远了怎么办?)
例如,查看所有标记(或字符,如果您需要转到该级别)并查找大括号。当找到开头的那个时,你会循环直到找到闭合支撑。那时,你开始寻找你的针,直到找到另一个开口支撑。它比Regex要多一些代码,但可能更容易阅读,也更容易排除故障。