Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 无限嵌套方括号的正则表达式_C#_Regex - Fatal编程技术网

C# 无限嵌套方括号的正则表达式

C# 无限嵌套方括号的正则表达式,c#,regex,C#,Regex,我正在寻找一个正则表达式(C#)来匹配以下情况: {a} {a:b} {a:{b} {a:{b:c} 等等 {a} {b} {a} {b}{c} 等等 a{b} {a} b a{b}{c} {a} b{c} {a} {b}c 等等 其中a、b、c可以是任何字符串 到目前为止,我得到了类似于:.[\{].+?[\}].*但这完全匹配案例{a}{b},而不是返回两个匹配,即{a}和{b} 表达式用于验证某个字符串是否为编码字符串。如果是,它需要从编码字符串中获取单独的片段(Regex.Match

我正在寻找一个正则表达式(C#)来匹配以下情况:

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

  • {a} {b}

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

  • a{b}

  • {a} b
  • a{b}{c}
  • {a} b{c}
  • {a} {b}c
  • 等等
其中a、b、c可以是任何字符串

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

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

Description 可以通过围绕正则表达式组合一些递归逻辑来实现这一点

这个正则表达式将匹配三层嵌套的开括号和闭括号,如
{a{b{c}}}{{d}e}f}

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

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

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

示例文本 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
        )

)
使用系统;
使用System.Text.RegularExpressions;
名称空间myapp
{
一班
{
静态void Main(字符串[]参数)
{
String sourcestring=“上面的示例文本”;
Regex re=new Regex(@“{((?:\{(?:\{.*}}}.*?)\}”),RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline);
MatchCollection mc=re.Matches(sourcestring);
int mIdx=0;
foreach(在mc中匹配m)
{
对于(int gIdx=0;gIdx阵列
(
[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] =>阵列
(
[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层。如本文所述,此表达式可能无法像
{a:{b}g{h}i}

中预期的那样处理捕获
g
,您还可以构建一个例程,该例程只解析示例字符串中的每个字符并跟踪嵌套深度

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
产量
您不能这样做,。这种语言不能与实际为正则表达式的正则表达式匹配,因为它需要一个下推自动机,而不是一个有限自动机。然而,现代的“正则”表达式实际上并不是正则的,所以可能有一种方法可以做到这一点。也就是说,我的建议是编写一个词法分析器和解析器,而不是尝试在正则表达式中这样做。第一个
etc
有点模糊,你是说任何括号深度,比如
{a:{b:{c:{d:{e:…
,都是可能的吗?如果是这样,正则表达式将无法解决你的问题。@dasblinkenlight:尽管“经典”是这样的正则表达式(支持交替、串联和Kleene星形运算符)无法识别具有嵌套参数的语言,现代“正则”表达式可以匹配某些下推自动机语言..NET特别支持“平衡组”--请看一个例子。我将按照Eric的建议使用解析器。括号的深度在理论上可以是无限的。谢谢你的帮助。即使它不是正则表达式,我也会检查你的答案。在理论上括号的深度可以是无限的,所以非正规的…你下面的另一个答案不会起作用。谢谢你的尝试h、 =)
$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
+ }