我正在尝试捕获由另一个关键字分隔的关键字的值,或者关键字的行尾可能以任何顺序重复或没有要捕获的数据:
关键词:K1,K2
输入数据:somedatahereornotk1capturethis1k2capturethis2k2capturethis3k1k2
我希望捕获的数据是
1. capturethis1
2. capturethis2
3. capturethis3
4.
5.
我试过k1|k2(?<Data>.*?)k1|k2
了,但捕获的数据总是空的。
谢谢!
你在交替的正确轨道上。缺少的部分是使用look-behind 和look-ahead 来断言某些东西必须在分隔符之前和之后。
(?<=k1|k2)(?<Data>.*?)(?=k1|k2)
Lookbehind(?<=…)
和lookahead(?=…)
是零宽度断言,因此它们必须满足但不成为匹配的一部分。
您捕获连续分隔符实例的愿望有点棘手,因为您无法真正捕获“无”——两个字符之间的空间。一种方法是捕获后视(或前瞻):
(?<=(?<Delimiter>k1|k2))(?<Data>.*?)(?=k1|k2)
这将产生 4 个结果而不是 3 个结果,因为它将包括k1k2
样本数据末尾的连续结果。您只需忽略每个匹配项的额外数据(k1
, k2
, k2
, k1
)。
首先,请注意交替运算符|
的优先级较低,因此
k1|k2(?<Data>.*?)k1|k2
实际上是在寻找k1
or k2(?<Data>.*?)k1
or k2
。使用分组:
(?:k1|k2)(?<Data>.*?)(?:k1|k2)
其次,考虑使用零宽度的lookahead 和lookbehind 断言:
(?<=k1|k2)(?<Data>.*?)(?=k1|k2)
string s="somedatahereornotk1capturethis1k2capturethis2k2capturethis3k1k2";
Regex r=new Regex("(?<=k1|k2).*?(?=k1|k2)");
foreach(Match m in r.Matches(s))
Console.WriteLine(m.Value);