0

我想从 plsql 源文件中提取函数内容。一个典型的函数看起来像这样

FUNCTION func_name;            // this could be there in the files

FUNCTION func_name
IS
   var_   Varchar2(100);
BEGIN
   InitSecurity('func_name')
   IF xxx THEN
      BEGIN
          xxxxx
      END;
   END IF;
END func_name;

我遇到的问题是主函数中可以嵌套多个 BEGIN 和 END。有没有办法提取整个函数记住这一点?

4

1 回答 1

1

如果你可以假设一个函数的 END 总是在行的开头没有缩进,而所有其他的都是缩进的,如果设置为多行模式m(大多数正则表达式引擎的标志),这个正则表达式将起作用。您还需要“点匹配所有内容”标志 ( s)。

FUNCTION\s+[a-z0-9_]+\s+IS\s+(.+?)^END

这里的技巧是^END,它告诉它只匹配行首的 END 。锚点仅在多行模式下具有^此含义,因此如果您的正则表达式引擎需要它,请确保添加 m 标志(Ruby 的不需要,大多数其他人需要)。

要分别捕获定义和代码:

FUNCTION\s+[a-z0-9_]+\s+IS\s+(.+?)\s+BEGIN\s+(.+?)^END

如果您总是在“END”语句中提供函数的名称,就像您在编辑中所做的那样,那么无论缩进如何,这个正则表达式都将起作用。您需要“点匹配所有内容”标志 ( s)。

FUNCTION\s+([a-z0-9_]+)\s+IS\s+(.+)\s+END\s+\1\s*;

这里我使用的是反向引用:END\s+\1\s*;将匹配 END,后跟至少一个空格,然后是函数名称(之前捕获的),然后是任意数量的空格和一个分号。

要分别捕获定义和代码:

FUNCTION\s+([a-z0-9_]+)\s+IS\s+(.+?)\s+BEGIN\s+(.+)\s+END\s+\1\s*;

如果您不能对缩进做出假设,并且如果所有函数在“END”语句中都没有它们的名称,那么我想不出一个可以完成这项工作的正则表达式。

当涉及到递归模式时,正则表达式通常不是正确的工具(好吧,一些高级正则表达式引擎中有一种方法可以递归整个模式,但它并不适用于所有情况,而且很难使用)。

所以我会用手做。循环遍历字符,检测函数的开头(您可以使用一个简单的正则表达式),然后为每个“BEGIN”递增一个计数器,并为每个“END”递减它(注意不要用“END IF”递减) )。当计数器降至零时,您的功能就结束了。

于 2013-08-04T19:47:06.073 回答