用于匹配嵌套花括号之间内容 (function/namespace) 的正则表达式

Regex for matching content (function/namespace) between nested curly braces

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

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

以下是我需要捕捉的东西:

  1. 主要class姓名

  2. 子class名字

  3. Sub classes 函数名称

  4. 各功能内容

我需要前 3 个来扫描我们所有的项目,以映射这些文件(及其功能)的使用位置。

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

代码示例:

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 ...
                }
            }
        }
    }
}

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

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

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

/{([^}]*)}/

然后(也在另一个任务中获取主要内容 class/namespace):

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

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

明确地说,首先我需要捕获这个(以获取主要 class 名称)及其内容:

public static class Utils {...}

***这个我居然懂了

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

1.

public static class Services {...}

2.

public static class SomeApi {...}

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

1.

public static int GetSomeIDBySomeName() {...}

2.

public static void UpdateViews() {...}

3.

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

在 Jeffrey Friedl 的书中 Mastering Regular Expressions there's a suitable sample on page 436.
How to match nested constructs is also explained at regular-expressions.info or weblogs.asp.net

来源中的示例更改为大括号将导致如下结果:

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

其中x对应嵌套深度。在 regexhero.net

进行测试
  • (?> 打开一个 atomic group
  • [^{}] 匹配一个不是大括号的字符
  • {(?<x>) 广告深度
  • }(?<-x>) 从 depth/stack
  • 中减去
  • (?(x)(?!)) 确保在满足最终 }
  • 之前深度为零

Reference - What does this regex mean

一般来说,嵌套的 something 语言与正则表达式 (常规语言)。常规语言具有不允许嵌套的语法,并使用确定性或非确定性有限状态自动机进行有效解析。上下文无关语言至少需要一个基于堆栈的自动机,它允许在某些地方存储括号级别(在这种情况下堆栈)为了能够使用正则表达式解析嵌套的括号表达式,您需要首先转换这些语言并使它们看起来几乎像上下文无关语言,但事实并非如此。只需为您允许您的语言解析的括号级别设置一个上限,您就会拥有一种常规语言。只有这样,您才能将上下文无关语言转换为常规语言。

随着一些语言(如 perl 或 python)对正则表达式的扩展,有一些方法可以部分(但不是一般)解决这个问题。

在您的例子中,您最多有 五级 括号(不仅计算花括号,还计算普通括号)。无论如何,您的自动机(以及允许解析五个级别的正则表达式)将很复杂。