正则表达式:从PL / SQL代码中分离过程/函数

时间:2010-09-24 05:27:10

标签: regex perl

我正在编写Perl正则表达式代码,以便从包中分离出PL / SQL过程。

每个过程以PROCEDURE关键字开始,以END结束,但END为BEGIN,IF或LOOP。可能有很多BEGIN | IF | LOOP。

下面是那种输入,我想分开每个程序。我怎么能这样做?

PROCEDURE LOG_ECS_MSG( MD_CURR  CHAR,
                     MSG_TIME DATE ) IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
BEGIN
INSERT INTO INFO_SERV_ECS_LOG
VALUES ( MD_CURR, MD, SVTY, ACT_DATE, ACCT, MSG_TXT, MSG_TIME);
COMMIT;
END;
END;




PROCEDURE LOG_ECS_MSG( MD_CURR  CHAR,
                     MSG_TIME DATE ) IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
IF....
INSERT INTO INFO_SERV_ECS_LOG
VALUES ( MD_CURR, MD, SVTY, ACT_DATE, ACCT, MSG_TXT, MSG_TIME);
COMMIT;
END IF
END;

3 个答案:

答案 0 :(得分:1)

最简单的方法是根据PROCEDURE的出现情况逻辑分隔文本:

undef $/;
my $line = <DATA>;
my @proc = split /(?=^PROCEDURE )/m, $line;
use Data::Dumper;
die Dumper \@proc;

答案 1 :(得分:0)

对于快速而肮脏的解决方案,查找令牌PROCEDURE可能足以分离代码块。但是,如果您希望这是一个成熟的解决方案,您应该尝试为PL / SQL找到(或编写)解析器并使用它。否则,您无法在字符串或注释中处理令牌PROCEDURE的出现。

答案 2 :(得分:0)

试试这个:

#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;

undef $/;
my $line = <DATA>;
my @procedures = split /(?=PROCEDURE)/, $line;
print Dumper(\@procedures);

__DATA__
PROCEDURE LOG_ECS_MSG( MD_CURR  CHAR,
                     MSG_TIME DATE ) IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
BEGIN
INSERT INTO INFO_SERV_ECS_LOG
VALUES ( MD_CURR, MD, SVTY, ACT_DATE, ACCT, MSG_TXT, MSG_TIME);
COMMIT;
END;
END;




PROCEDURE LOG_ECS_MSG( MD_CURR  CHAR,
                     MSG_TIME DATE ) IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
IF....
INSERT INTO INFO_SERV_ECS_LOG
VALUES ( MD_CURR, MD, SVTY, ACT_DATE, ACCT, MSG_TXT, MSG_TIME);
COMMIT;
END IF
END;

输出:

$VAR1 = [
          'PROCEDURE LOG_ECS_MSG( MD_CURR  CHAR,
                     MSG_TIME DATE ) IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
BEGIN
INSERT INTO INFO_SERV_ECS_LOG
VALUES ( MD_CURR, MD, SVTY, ACT_DATE, ACCT, MSG_TXT, MSG_TIME);
COMMIT;
END;
END;




',
          'PROCEDURE LOG_ECS_MSG( MD_CURR  CHAR,
                     MSG_TIME DATE ) IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
IF....
INSERT INTO INFO_SERV_ECS_LOG
VALUES ( MD_CURR, MD, SVTY, ACT_DATE, ACCT, MSG_TXT, MSG_TIME);
COMMIT;
END IF
END;'
        ];