PL/SQL-REGEXP_LIKE

Posted

技术标签:

【中文标题】PL/SQL-REGEXP_LIKE【英文标题】:PL/SQL- REGEXP_LIKE 【发布时间】:2010-12-13 10:54:52 【问题描述】:

我正在编写一个程序,它从存储库中读取一些 PL/SQL 代码,然后验证每个程序/函数是否具有适当的文档标题。给出变量 my_code 中包含的以下 PL/SQL 代码:

my_code varchar2(1024) := '
  script package test_lib
  is
     -------------------------------------------------------------------------------
     -- <function name="my_func" begin="9-Dec-2010">
     --   <summary>
     --     Test function.
     --   </summary>
     --   <authors>
     --     <author name="Giuseppe Greco" email="giuseppe.greco@b-source.ch"/>
     --   </authors>
     --   <params>
     --     <param name="num" mandatory="yes" type="input">
     --       Test param.
     --     </param>
     --   </params>
     --   <return>
     --     True if it is an alarm; otherwise, false.
     --   </return>
     -- </function>
     --------------------------------------------------------------------------------
     function my_func(par1 NUMBER)
     return boolean
     is
       l_num NUMBER := 0;
     begin
       if l_num < 1 then
         dbms_output.put_line(''my_func'');
       end if;
       return true;
     end my_func;
   end test_lib;
 ';

我尝试过类似的方法......但它不起作用:

if REGEXP_LIKE(my_code, 'function (\w).+end \1;') then
    l_number_of_funcs := LENGTH(
        REGEXP_REPLACE(
            my_code,
            '([^f]+[^u]+[^n]+[^c]+[^t]+[^i]+[^o]+[^n]+)(.+)is(.*)begin(.*)end([a-z0-9_\-]+);'));
end if;

在上述语句中,REGEXP_LIKE 永远不会返回 true,因此永远不会执行 REGEXP_REPLACE。我正在做的是确定代码是否至少包含一个过程,如果包含,我调用 REGEXP_REPLACE 来确定代码包含多少个过程(在上面的示例中,它应该返回 1)。我首先调用 REGEXP_LIKE,因为如果代码不包含任何过程,REGEXP_REPLACE 就会崩溃。

有什么想法或建议吗?任何帮助将不胜感激。

谢谢, 杰夫

【问题讨论】:

【参考方案1】:

    尝试更简单的正则表达式

    '^.*function.*return.*(is|as).*begin.*end'
    

    REGEXP_COUNT 函数可能更适合这种情况。

    多行的存在会严重破坏这一点。如果有多行,即使上面 (1) 中的简化正则表达式也不起作用。我建议你编写一个注释剥离器和换行器,通过这些函数传递你的代码字符串,然后通过正则表达式运行它。

在任何情况下,使用正则表达式来解析文本往往不如预期的那么有用。您确实需要一个 PL/SQL 解析器 - 请参阅

http://database-geek.com/2009/02/06/building-a-plsql-code-parser-using-plsql-part-1-2/

分享和享受。

【讨论】:

不幸的是,我们使用不支持 REGEXP_COUNT 的 Oracle 9.2 - 这是我的第一次尝试 :-)【参考方案2】:

我认为使用 NVL 您不需要两次检查。试试:

l_number_of_funcs := 
NVL(LENGTH(REGEXP_REPLACE(l_code,'(f)unction [^(]+\(|.','\1',1,0,'in')),0);

我无法对此进行测试,但它应该朝着正确的方向发展。

【讨论】:

嗨 morja,非常感谢您的回答...但它不像我预期的那样工作。语句执行后,l_number_of_funcs 为 20,而应该为 1(在示例中,代码只包含一个函数)。 您的示例文本看起来如何?当我尝试正则表达式时:“测试程序结束;测试任何程序结束;”我得到 pp 作为结果字符串和 2 作为长度...... 试试这个:声明 l_code varchar2(999) := ' 脚本包 mb0_test_lib is function my_func(par1 NUMBER) return boolean is l_num NUMBER := 0;如果 l_num 0 则 dbms_output.put_line('Nr of functions: ' || l_funcs);万一;结束; 好的,我明白了。除了作为过程声明之外,“过程”是否可能出现在其他地方?如果没有,您可以按照我在编辑后的帖子中所做的那样做。 正如 Bob Jarvis 所说,问题可能出在换行符上。我更新了 REGEXP_REPLACE 并添加了 i = 忽略大小写和 n = dot 匹配所有参数。

以上是关于PL/SQL-REGEXP_LIKE的主要内容,如果未能解决你的问题,请参考以下文章