在比赛中加入错误的组

时间:2015-10-17 17:17:29

标签: c# regex

我有一个这样的字符串:

  

& 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+)

比赛结果如下:
enter image description here
您可以看到子字符串&l&e&j未包含在匹配项中。我知道\w+的问题,但我似乎无法弄清楚如何包含这些匹配。第一组应该只包含匹配&[lmnor]的任何内容(如果它们靠得很近,它可以包含多个。这就是我使用+的原因。第二组应该包含除这些字母之外的任何内容。
(&[lmnor])+(.*)不起作用。 (&[lmnor])+^(&[lmnor])+也没有。

2 个答案:

答案 0 :(得分:1)

  

您可以看到子字符串&l&e&j未包含在匹配项中。我知道\w+的问题,但我似乎无法弄清楚如何包含这些匹配。

很明显,&不是单词字符。这就是为什么没有匹配/捕获带有&符号的子字符串的原因。

  

第一组应该只包含匹配& [lmnor]的任何内容(如果它们靠得很近,它可以包含多个。

当我们应该在捕获组中使用具有量词的非捕获组时,就是这种情况:((?:&[lmnor])+)。我们匹配字符序列并将所有文本块捕获到一组中。

  

第二组应包含除这些字母以外的任何内容。

tempered greedy token(?:(?!&[lmnor]).)*来说,这是一个完美的工作。它匹配任何未启动&[lmnor]子字符串的文本。我们不能使用否定的字符类,因为要跳过的符号是2(不是单个字符)。

因此,您可以使用以下正则表达式:

((?:&[lmnor])+)((?:(?!&[lmnor]).)*)

请参阅regex demo

您可以使用另一个正则表达式遵循相同的逻辑,但使用延迟点匹配和用字符串结尾或第一组符号&[lmnor]的正向前瞻检查表示的边界:

((?:&[lmnor])+)(.*?)(?=$|&[lmnor])

请参阅another regex demo

答案 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