正则表达式匹配不包括特定上下文

时间:2016-10-12 13:21:48

标签: c# regex

我试图在字符串中搜索单引号内的单词,但前提是这些单引号不在括号内。

示例字符串: something, 'foo', something ('bar')

因此,对于给定的示例,我希望匹配foo,而不是bar

在搜索正则表达式示例后,我能够在单引号内匹配(请参阅下面的代码段),但我不确定如何在前面描述的上下文中排除匹配。

string line = "something, 'foo', something ('bar')";
Match name = Regex.Match(line, @"'([^']*)");
if (name.Success)
{
    string matchedName = name.Groups[1].Value;
    Console.WriteLine(matchedName);
}

2 个答案:

答案 0 :(得分:3)

我建议使用lookahead(参见live)使用:

(?<!\()'([^']*)'(?!\))

或者使用C#:

string line = "something, 'foo', something ('bar')";
Match name = Regex.Match(line, @"(?<!\()'([^']*)'(?!\))");
if (name.Success)
{
    Console.WriteLine(name.Groups[1].Value);
}

答案 1 :(得分:2)

获得所需内容的最简单方法是使用一个交替组,匹配并捕获您需要的内容,并且只匹配您不需要的内容:

\([^()]*\)|'([^']*)'

请参阅regex demo

<强>详情:

  • \( - (
  • [^()]* - 除()
  • 以外的0个字符
  • \) - )
  • | - 或
  • ' - '
  • ([^']*) - 第1组捕获除'
  • 以外的0 +字符
  • ' - 单引号。

在C#中,使用.Groups[1].Value获取所需的值。请参阅online demo

var str = "something, 'foo', something ('bar')";
var result = Regex.Matches(str, @"\([^()]*\)|'([^']*)'")
    .Cast<Match>()
    .Select(m => m.Groups[1].Value)
    .ToList();

另一个选择是Thomas提到的那个,但由于它是.NET,你可以使用无限宽度的lookbehind

(?<!\([^()]*)'([^']*)'(?![^()]*\))

请参阅this regex demo

<强>详情:

  • (?<!\([^()]*) - 如果(后跟0 {+ 1}}和(以及<{li}以外的0 +字符,则会导致比赛失败
  • ) - 引用,0 +字符除了单引号捕获到第1组,另有单引号
  • '([^']*)' - 如果在(?![^()]*\))之后有{+ 1}}和(以及)之后有0个字符,则会导致匹配失败。来自前面的子模式。

由于您要排除),因此适用与上述相同的代码。