3

我正在尝试捕获由另一个关键字分隔的关键字的值,或者关键字的行尾可能以任何顺序重复或没有要捕获的数据:

关键词:K1,K2

输入数据:somedatahereornotk1capturethis1k2capturethis2k2capturethis3k1k2

我希望捕获的数据是

1. capturethis1
2. capturethis2
3. capturethis3
4. 
5.

我试过k1|k2(?<Data>.*?)k1|k2了,但捕获的数据总是空的。

谢谢!

4

3 回答 3

3

你在交替的正确轨道上。缺少的部分是使用look-behind 和look-ahead 来断言某些东西必须在分隔符之前和之后。

(?<=k1|k2)(?<Data>.*?)(?=k1|k2)

Lookbehind(?<=…)和lookahead(?=…)是零宽度断言,因此它们必须满足但不成为匹配的一部分。

您捕获连续分隔符实例的愿望有点棘手,因为您无法真正捕获“无”——两个字符之间的空间。一种方法是捕获后视(或前瞻):

(?<=(?<Delimiter>k1|k2))(?<Data>.*?)(?=k1|k2)

这将产生 4 个结果而不是 3 个结果,因为它将包括k1k2样本数据末尾的连续结果。您只需忽略每个匹配项的额外数据(k1, k2, k2, k1)。

于 2012-08-15T14:16:49.453 回答
3

首先,请注意交替运算符|的优先级较低,因此

k1|k2(?<Data>.*?)k1|k2

实际上是在寻找k1or k2(?<Data>.*?)k1or k2。使用分组:

(?:k1|k2)(?<Data>.*?)(?:k1|k2)

其次,考虑使用零宽度的lookahead 和lookbehind 断言:

(?<=k1|k2)(?<Data>.*?)(?=k1|k2)
于 2012-08-15T14:16:54.307 回答
0
string s="somedatahereornotk1capturethis1k2capturethis2k2capturethis3k1k2";

Regex r=new Regex("(?<=k1|k2).*?(?=k1|k2)");
foreach(Match m in r.Matches(s))
Console.WriteLine(m.Value);
于 2012-08-15T14:54:50.243 回答