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

本文关键字:上下文 不包括 正则表达式 | 更新日期: 2023-09-27 18:12:48

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

示例字符串: 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);
}

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

我建议使用前瞻(实时查看(:

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

或者使用 C#:

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

获取所需内容的最简单方法是使用交替组并匹配和捕获所需内容,并且仅匹配不需要的内容:

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

查看正则表达式演示

详情

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

在 C# 中,使用 .Groups[1].Value 获取所需的值。查看在线演示:

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

另一种选择是 Thomas 提到的一种,但由于它是 .NET,您可以使用无限宽的后视:

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

请参阅此正则表达式演示。

详情

  • (?<!'([^()]*) - 如果后面有 ( 个字符,则为负回头,后跟 0+ 字符,而不是 ()
  • '([^']*)' - 一个引号,捕获
  • 到组中 1 的单引号以外的 0+ 字符,以及另一个单引号
  • (?![^()]*')) - 一个负的展望,如果除了 ( 之外有 0+ 个字符,并且)在前面子模式的'之后紧跟),则匹配失败。

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