正则表达式 - 匹配 BEGIN 和 END 之间的所有内容

Posted

技术标签:

【中文标题】正则表达式 - 匹配 BEGIN 和 END 之间的所有内容【英文标题】:Regular Expression - Match all between BEGIN and END 【发布时间】:2018-08-24 08:29:48 【问题描述】:

我正在尝试找出如何创建一个正则表达式来匹配过程块的第一个“BEGIN”和最后一个“END”之间的所有文本。

这是我要过滤的文本:

PROCEDURE MyFirstFunction()@12345
VAR
    TESTVAR@1 : Record 1;
    TESTVAR@2 : Record 2;
BEGIN
    // Here begins the code
    IF 1 = 1 THEN BEGIN
        IF 2 <> 1 THEN BEGIN
            MESSAGE('2 is not equal to 1');
        END;
        MESSAGE('1 is equal to 1');
    END;
END;

PROCEDURE MySecondFunction()@123456
VAR
    TESTVAR@1 : Record 1;
    TESTVAR@2 : Record 2;
BEGIN
    // Here begins the code
    IF 1 = 1 THEN BEGIN
        IF 2 <> 1 THEN BEGIN
            MESSAGE('2 is not equal to 1');
        END;
        MESSAGE('1 is equal to 1');
    END;
END;

PROCEDURE MyThirdFunction()@123457
VAR
    TESTVAR@1 : Record 1;
    TESTVAR@2 : Record 2;
BEGIN
    // Here begins the code
    IF 1 = 1 THEN BEGIN
        IF 2 <> 1 THEN BEGIN
            MESSAGE('2 is not equal to 1');
        END;
        MESSAGE('1 is equal to 1');
    END;
END;

我已经尝试过使用递归正则表达式,但这不起作用。

这是我处理的正则表达式:

BEGIN(((?!BEGIN|END;).)|(?R))*END;

但我只得到第一个函数的第二个开头。

这里是 regex101.com 的链接,用于测试正则表达式: https://regex101.com/r/ZoBm6h/1

【问题讨论】:

可能,你可以使用(?sm)^BEGIN$.*?^END;$。或者,(?sm)^BEGIN$(((?!^(?:BEGIN|END;)$).)|(?R))*^END;$ 正则表达式不是词法分析的工具。使用 ANTLR 或类似的东西... 你好维克托和安德鲁。致 Wiktor:谢谢,但是当涉及到像这种情况下的复杂代码块时:regex101.com/r/t6bEcT/1 模式不再起作用。致 Andrew:我要查找 ANTLR,谢谢您的回答! @Kevin 我认为我的回答可能仍然可以用您的数据挽救。查看我上一条评论下的更新演示链接。 @Kevin with sed 命令使用 2 个缓冲区和正则表达式,并且可以为其提供脚本,您将能够执行您想要的操作,请参阅 grymoire.com/Unix/Sed.html 此备注也适用于awkgrymoire.com/Unix/Awk.html 【参考方案1】:

我认为你想要的负前瞻逻辑是它应该贪婪地消耗BEGIN 之后的所有内容,直到到达最后一个END,前提是它也没有看到文本PROCEDURE,这意味着它是走得太远了,已经进入下一个程序块了。

BEGIN((?!PROCEDURE).)*END;

Demo

【讨论】:

你好,蒂姆。当涉及到复杂的代码块时,这种模式不起作用:regex101.com/r/t6bEcT/1 .. @Kevin 是的,it does work。您需要为换行打开 DOT ALL 模式。正如 cmets 所说,如果您无法获得一个相当简单的正则表达式来执行您想要的操作,那么您真的应该使用正式的解析器。正则表达式不能很好地处理嵌套内容,而代码正是如此。 谢谢。是的,我看见它了! :) 太棒了。如果您不介意,我还有最后一个问题:如何获取过程的名称(如 PROCEDURE TestMethod@1234 和下面的变量块)以及声明的变量也带有正则表达式 - 我会自己尝试一下但是,当您有某种建议或解决方案时,请现在告诉我。 :-) 您应该使用您使用的语言更新您的问题。添加捕获组不会在正则表达式演示工具中运行太多。 该语言被称为 C/AL - 这是非常罕见的。 :-)【参考方案2】:

如果你想匹配所有块,你也可以使用这个Regex:

BEGIN((?!^(?!PROCEDURE)$).)*END

【讨论】:

你的答案基本上是我的副本。而且,最重要的是,your answer doesn't work。

以上是关于正则表达式 - 匹配 BEGIN 和 END 之间的所有内容的主要内容,如果未能解决你的问题,请参考以下文章

Linux AWK学习

正则表达式 - 匹配任何单词但忽略特定单词[重复]

正则表达式匹配以某个字符串开头的后面部分的字符串

正则表达式匹配逗号不在分组符号之间

Python 正则表达式 - 了解匹配和搜索之间的区别

正则表达式匹配字母和数字,其中一些符号可以出现在它们之间