编写正则表达式以捕获外括号之间的文本

时间:2010-08-12 15:01:09

标签: .net regex balancing-groups

所以我试图解析一个文件格式为:

outerkey = (innerkey = innervalue)

它变得更复杂。这在文件中也是合法的:

outerkey = (innerkey = (twodeepkey = twodeepvalue)(twodeepkey2 = twodeepvalue2))

所以我想基本上只捕获外键的文本。我无法保证所有文字都在一行上。该值可能在多行上。并且文件中有多个项目。

到目前为止,这是我的正则表达式:

[^\s=]+\s*=\s*(\(\s*.*\s*\))

我的目标是简单地用我想要搜索的键替换第一部分[^\s=]+,然后获得外括号的整个文本。

这是问题所在。我的正则表达式不仅会捕获我想要捕获的文本,而且还会捕获下一组中的文本,因为正则表达式是贪婪的。让它不贪婪也行不通,因为它会在第一个右括号处停止捕获。

最终,如果我有以下字符串

foo = 
(
  ifoo = ifoov
)

bar =
(
  ibar =
    (iibar = iibarv)
    (iibar2 = iibarv2)
)

我希望这些群组匹配

(
  ifoo = ifoov
)

(
  ibar =
    (iibar = iibarv)
    (iibar2 = iibarv2)
)

现在它将匹配

(
  ifoo = ifoov
)

bar =
(
  ibar =
    (iibar = iibarv)
    (iibar2 = iibarv2)
)

顺便说一下,我在多线和单线模式下运行它。

有什么想法吗?谢谢!

2 个答案:

答案 0 :(得分:3)

我能够针对此问题调整balancing group definition .NET正则表达式功能,如下所示:

Regex r = new Regex(@"(?x) # for sanity!

    (?'Key' [^=\s]* )
    \s*=\s*
    (?'Value'
      (
         (
           [^()]*
           (?'Open'\()
         )+
         (
           [^()]*
           (?'Close-Open'\))
         )+
      )+?
    )
    (?(Open)(?!))

");

我们可以按如下方式测试它:

var text = @"
foo = 
(
  ifoo = ifoov
)

bar =
(
  ibar =
    (iibar = iibarv)
    (iibar2 = iibarv2)
)

outerkey = (innerkey = (twodeepkey = twodeepvalue)(twodeepkey2 = twodeepvalue2))
";

foreach (Match m in r.Matches(text)) {
  Console.WriteLine("Key: [{0}]", m.Groups["Key"]);
  Console.WriteLine("Value: [{0}]", m.Groups["Value"]);
  Console.WriteLine("-------");
}
Console.WriteLine("That's all folks!");

打印(as seen on ideone.com):

Key: [foo]
Value: [(
  ifoo = ifoov
)]
-------
Key: [bar]
Value: [(
  ibar =
    (iibar = iibarv)
    (iibar2 = iibarv2)
)]
-------
Key: [outerkey]
Value: [(innerkey = (twodeepkey = twodeepvalue)(twodeepkey2 = twodeepvalue2))]
-------
That's all folks!

文档中示例模式的一些小修改是:

  • 开启 - 关闭 - 现在\( - \) - [^()]而不是< - > - [^<>]
  • 使用+?(至少一个,但尽可能少)而不是*
  • 重复平衡结构
  • “content”在括号之前匹配,而不是在括号之后

答案 1 :(得分:2)

一般来说,regexp无法计算匹配,所以这不容易实现。但是,.NET有一个名为“平衡组定义”The example here shows how to match paired angle brackets的功能,应该可以帮到那里......