4

我正在寻找与以下情况匹配的正则表达式(在 C# 中):

  • {一个}
  • {a:b}
  • {a:{b}}
  • {a:{b:c}}
  • 等等

  • {a}{b}

  • {a}{b}{c}
  • 等等

  • 一个{b}

  • {a}b
  • 一个{b}{c}
  • {a}b{c}
  • {a}{b}c
  • 等等

其中 a、b、c 可以是任意字符串。

到目前为止,我有类似:.*[\{].+?[\}].*但这完全匹配案例{a}{b},而不是返回两个匹配项,即{a}{乙}

该表达式用于验证某个字符串是否为编码字符串。如果是,它需要从编码字符串中获取单独的部分(Regex.Matches() 会很方便)并解析它们。

4

2 回答 2

1

描述

您可以通过围绕正则表达式组合一些递归逻辑来做到这一点

这个正则表达式将匹配嵌套三层深的左括号和右括号{a{b{c}}}{{{d}e}f}

\{((?:\{(?:\{.*?\}|.)*?\}|.)*?)\}

在此处输入图像描述

虚线区域是基本搜索,其中该搜索嵌套在其自身内部,可根据需要嵌套多个层。

在下面的示例中,我只是针对您的大多数示例运行正则表达式。将此正则表达式与一个 foreach 循环结合起来,该循环将采用每个组 1 并从当前字符串的开头捕获所有非开括号^[^{]*,然后通过上面的正则表达式递归地返回字符串的其余部分以捕获下一组括号内的值,然后从字符串末尾捕获所有非右括号[^}]*$

示例文本

{a}
{a:b}
{a:{b}}
{a:{b:c}}
{a}{b}
{a}{b}{c}
{a{b{c}}}{{{d}e}f}

C#.NET 代码示例:

此 C#.Net 示例仅显示正则表达式的工作原理。查看第 1 组如何从最外面的括号组中获取内部文本。每个外括号文本都被分解成它自己的数组位置,并且相应的外括号被删除。

using System;
using System.Text.RegularExpressions;
namespace myapp
{
  class Class1
    {
      static void Main(string[] args)
        {
          String sourcestring = "sample text above";
          Regex re = new Regex(@"\{((?:\{(?:\{.*?\}|.)*?\}|.)*?)\}",RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline);
          MatchCollection mc = re.Matches(sourcestring);
          int mIdx=0;
          foreach (Match m in mc)
           {
            for (int gIdx = 0; gIdx < m.Groups.Count; gIdx++)
              {
                Console.WriteLine("[{0}][{1}] = {2}", mIdx, re.GetGroupNames()[gIdx], m.Groups[gIdx].Value);
              }
            mIdx++;
          }
        }
    }
}
$matches Array:
(
    [0] => Array
        (
            [0] => {a}
            [1] => {a:b}
            [2] => {a:{b}}
            [3] => {a:{b:c}}
            [4] => {a}
            [5] => {b}
            [6] => {a}
            [7] => {b}
            [8] => {c}
            [9] => {a{b{c}}}
            [10] => {{{d}e}f}
        )

    [1] => Array
        (
            [0] => a
            [1] => a:b
            [2] => a:{b}
            [3] => a:{b:c}
            [4] => a
            [5] => b
            [6] => a
            [7] => b
            [8] => c
            [9] => a{b{c}}
            [10] => {{d}e}f
        )

)

免责声明

此表达式仅适用于第三级递归。外部文本需要单独处理。.net 正则表达式引擎确实提供递归计数,并且可能支持 N 层深度。如此处所写,此表达式可能无法g按预期处理捕获{a:{b}g{h}i}

于 2013-06-05T23:01:06.483 回答
1

您还可以构建一个例程,它只解析示例字符串中的每个字符并跟踪嵌套深度。

Powershell 示例

我提供这个 powershell 示例是因为我有一个方便的 powershell 控制台。这只是为了演示该功能如何工作。

$string = '{a}
{a:b}
a:{b}g{h}ik
{a:{b:c}}
{a}{b}
{a}{b}{c}
{a{b{c}}}{{{d}e}f}
'

$intCount = 0

# split the string on the open and close brackets, the round brackets ensure the squiggly brackets are retained
foreach ($CharacterGroup in $string -split "([{}])") {
    write-host $("+" * $intCount)$CharacterGroup
    if ($CharacterGroup -match "{") { $intCount += 1 }
    if ($CharacterGroup -match "}") { $intCount -= 1 }
    if ($intCount -lt 0) { 
        Write-Host "missing close bracket"
        break
        } # end if
    } # next $CharacterGroup

产量

 {
+ a
+ }


 {
+ a:b
+ }

a:
 {
+ b
+ }
 g
 {
+ h
+ }
 ik

 {
+ a:
+ {
++ b:c
++ }
+ 
+ }


 {
+ a
+ }

 {
+ b
+ }


 {
+ a
+ }

 {
+ b
+ }

 {
+ c
+ }


 {
+ a
+ {
++ b
++ {
+++ c
+++ }
++ 
++ }
+ 
+ }

 {
+ 
+ {
++ 
++ {
+++ d
+++ }
++ e
++ }
+ f
+ }
于 2013-06-06T00:58:02.217 回答