我有一个这样的字符串:
& l& mmabc& amp& l& r& mef& lg& l& e& j& rh
我想获得以下比赛和小组。 (将括号视为组和要匹配的行)
(&l&m)(mabc)
(&o)(d)
(&l&r&m)(ef)
(&l)(g)
(&l)(&e&j)
(&r)(h)
到目前为止,我已经得到了这个:
(&[lmnor])+(\w+)
比赛结果如下:
您可以看到子字符串&l&e&j
未包含在匹配项中。我知道\w+
的问题,但我似乎无法弄清楚如何包含这些匹配。第一组应该只包含匹配&[lmnor]
的任何内容(如果它们靠得很近,它可以包含多个。这就是我使用+
的原因。第二组应该包含除这些字母之外的任何内容。
(&[lmnor])+(.*)
不起作用。 (&[lmnor])+^(&[lmnor])+
也没有。
答案 0 :(得分:1)
您可以看到子字符串
&l&e&j
未包含在匹配项中。我知道\w+
的问题,但我似乎无法弄清楚如何包含这些匹配。
很明显,&
不是单词字符。这就是为什么没有匹配/捕获带有&
符号的子字符串的原因。
第一组应该只包含匹配& [lmnor]的任何内容(如果它们靠得很近,它可以包含多个。
当我们应该在捕获组中使用具有量词的非捕获组时,就是这种情况:((?:&[lmnor])+)
。我们匹配字符序列并将所有文本块捕获到一组中。
第二组应包含除这些字母以外的任何内容。
对tempered greedy token:(?:(?!&[lmnor]).)*
来说,这是一个完美的工作。它匹配任何未启动&[lmnor]
子字符串的文本。我们不能使用否定的字符类,因为要跳过的符号是2(不是单个字符)。
因此,您可以使用以下正则表达式:
((?:&[lmnor])+)((?:(?!&[lmnor]).)*)
请参阅regex demo
您可以使用另一个正则表达式遵循相同的逻辑,但使用延迟点匹配和用字符串结尾或第一组符号&[lmnor]
的正向前瞻检查表示的边界:
((?:&[lmnor])+)(.*?)(?=$|&[lmnor])
答案 1 :(得分:0)
使用内置的电源可以减少复杂性 C#正则表达式。
这显示使用Capture Collections,我相信速度更快。
C#
Match aM = Regex.Match(
@"&l&mmabc&od&l&r&mef&lg&l&e&j&rh",
@"^(?:((?:&[lmnor])+)(.*?))+$" );
if ( aM.Success ) {
CaptureCollection cc1 = aM.Groups[1].Captures;
CaptureCollection cc2 = aM.Groups[2].Captures;
for (int i = 0; i < cc1.Count; i++)
Console.WriteLine("[{0}] = {1} {2}", i, cc1[i].Value, cc2[i].Value);
}
输出:
[0] = &l&m mabc
[1] = &o d
[2] = &l&r&m ef
[3] = &l g
[4] = &l &e&j
[5] = &r h