用于在嵌套花括号

时间:2015-08-30 13:18:24

标签: c# regex curly-braces

我在这里已经阅读了很多关于匹配和捕获文本中花括号之间的字符串的主题,但没有找到答案,用于匹配和捕获函数的内容(特别是在内部有一些逻辑的情况下)。所以希望这个主题不会重复。

我需要匹配代码文件中的几个东西(我有很多东西,所有这些东西都有相似的结构,但深度不同),如下所示。

以下是我需要捕捉的内容:

  1. 主要班级名称

  2. 子类名称

  3. 子类函数名称

  4. 每项功能的内容

  5. 我需要先扫描所有项目,然后映射这些文件(及其功能)的使用位置。

    最后一个需要再次匹配可以在这些函数中使用的列表特定服务(内部和外部)。

    代码示例:

    namespace Myprogramm.BusinessLogic
    {
        public static class Utils
        {
            public static class Services
            {
                public static int GetSomeIDBySomeName()
                {
                    // call some webservice
                }
    
                public static void UpdateViews()
                {
                    // send some request
                }
    
                public static void IncreaseViews(int views)
                {
                    if (views < 1000)
                    {
                        // execute SQL SP1
                    }
                    else
                    {
                        // execute SQL SP2
                    }
                }
            }
    
            public static class SomeApi
            {
                public int OpenSomeSession(int someId)
                {
                    if (someId < 0)
                    {
                        // do something...
                    }
                    else
                    {
                        // do something else ...
                    }
                }
            }
        }
    }
    

    我正在尝试做的是将这些文件作为文本阅读,并将其内容与某些正则表达式进行匹配,以捕获我需要的内容。

    我是正则表达式的新手。所以我在这里没有取得很大的成功。 我无法弄清楚,如何匹配和捕获子类的内容,然后我如何为函数做同样的事情。

    我尝试使用这个(在另一个任务中)捕获简单函数的内容(内部没有逻辑):

    /{([^}]*)}/
    

    有了这个(在另一个获取主类/命名空间内容的任务中):

    /{([\s\S]*)}/
    

    而且我明白,为什么这对我这个任务没有帮助。

    要明确的是,首先我需要捕获这个(获取主类名称)并且它是内容:

    public static class Utils {...}
    

    ***我真正了解这个

    然后那两个(捕获子类名称及其内容):

    1

    public static class Services {...}
    

    2

    public static class SomeApi {...}
    

    然后(仅以第一个子类为例):

    1

    public static int GetSomeIDBySomeName() {...}
    

    2

    public static void UpdateViews() {...}
    

    3

    public static void IncreaseViews(int views) { if (views < 1000) {...} else {...} }
    

2 个答案:

答案 0 :(得分:1)

在Jeffrey Friedl的书Mastering Regular Expressions中,有一个合适的sample on page 436。如何匹配嵌套构造也在{{ 3}}或regular-expressions.info

源中的示例更改为大括号将导致类似这样的内容:

{(?>[^{}]+|{(?<x>)|}(?<-x>))*(?(x)(?!))}

x对应嵌套深度。在weblogs.asp.net

进行测试
  • (?>打开regexhero.net
  • [^{}]匹配一个不是大括号的字符
  • {(?<x>)广告深度
  • }(?<-x>)从深度/堆栈中减去
  • (?(x)(?!))确保在遇到最终}
  • 之前深度为零

atomic group

答案 1 :(得分:0)

通常,嵌套的某些语言与正则表达式定义的语言(常规语言)处于不同的组织(上下文无关语言)中)。常规语言具有不允许嵌套的语法,并且使用确定性或非确定性有限状态自动机有效地解析。上下文无关语言至少需要一个基于堆栈的自动机,它允许在某些地方(在这种情况下堆栈)稍微存储括号级别以便能够解析嵌套使用正则表达式的括号表达式,您需要首先转换这些语言并使它们看起来几乎像上下文无关语言,但不是这样。只需将上限绑定到允许语言解析的括号级别,您就可以使用常规语言。只有这样,您才能将无上下文的语言转换为常规语言。

使用某些语言的扩展(如perl或python)制作regexp,有一些方法可以部分地(但不是一般地)应对这种情况。

在您的情况下,您有最多五个级别的括号(不仅计算大括号,还计算括号)。无论如何,你的自动机(以及允许解析五个级别的正则表达式)将是复杂的。