【问题标题】:Regular Expression - Match all between BEGIN and END正则表达式 - 匹配 BEGIN 和 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

【问题讨论】:

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

标签: regex string filter expression


【解决方案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

【讨论】:

猜你喜欢
  • 2018-09-02
  • 2018-12-02
  • 1970-01-01
  • 1970-01-01
  • 2013-10-31
  • 2020-01-20
  • 1970-01-01
  • 1970-01-01
  • 2011-04-13
相关资源
最近更新 更多