如何在Regex上使用Lookahead

时间:2019-04-05 21:07:45

标签: regex powershell

我有一个sql脚本可以在oracle上创建或替换软件包,我需要检查查询是否使用“ user”。“ object”之类的Schema语法,以获取有关Create或alter table的说明。正则表达式很简单,但是对于create Package来说,对我而言并不那么容易,因为在某些情况下它可以包含单词“ BODY”。

假设我的文件包含以下几行(以及其他内容):

CREATE OR REPLACE PACKAGE PKG_MASSIVE_SERVICE_AUTOMIC 
CREATE OR REPLACE PACKAGE AUTOMIC.PKG_MASSIVE_SERVICE_AUTOMIC 
CREATE OR REPLACE PACKAGE BODY PKG_MASSIVE_SERVICE_AUTOMIC 
CREATE OR REPLACE PACKAGE BODY AUTOMIC.PKG_MASSIVE_SERVICE_AUTOMIC 

第二行和第四行是唯一有效的,我如何只匹配无效查询,即第一行和第三行?

我尝试使用:

^CREATE\sOR\sREPLACE\sPACKAGE\s[a-zA-Z_0-9]+\s

但是它返回:

CREATE OR REPLACE PACKAGE PKG_MASSIVE_SERVICE_AUTOMIC
CREATE OR REPLACE PACKAGE BODY PKG_MASSIVE_SERVICE_AUTOMIC
CREATE OR REPLACE PACKAGE BODY AUTOMIC.PKG_CLAUSE_TIME_V1_241_AUTOMIC

然后我尝试使用后向导航”

CREATE\sOR\sREPLACE\sPACKAGE\s(?=BODY\s)[a-zA-Z_0-9]+\s

但也不起作用。

这是一个示例脚本文件:

CREATE OR REPLACE PACKAGE PKG_MASSIVE_SERVICE_AUTOMIC 
  IS
   Type REF_CUR Is Ref Cursor;

PROCEDURE PRC_GETACTIVATIONINFO_ARUS
(
    VIDACTIVACION IN NUMBER,
    RES_CURSOR OUT REF_CUR
);

PROCEDURE PRC_GETPAYMENTINFO_ARUS
(
    VIDACTIVACION IN NUMBER,
    RES_CURSOR OUT REF_CUR
);

PROCEDURE PRC_GETACTIVAPROCESSINFO_ARUS
(
    VIDACTIVACION IN NUMBER,
    RES_CURSOR OUT REF_CUR
);

PROCEDURE PRC_UPDATEPAGOS_ARUS
(
    VIDACTIVACION IN NUMBER,
    VIDPAGOSACTIVACION IN NUMBER
);
PROCEDURE PRC_GETACTPROCSBILLINGINF_ARUS
(
    VIDACTIVACION IN NUMBER,
    RES_CURSOR OUT REF_CUR
);
END;
 /
 CREATE OR REPLACE PACKAGE BODY PKG_MASSIVE_SERVICE_AUTOMIC 
 IS
  PROCEDURE PRC_GETACTIVATIONINFO_ARUS

3 个答案:

答案 0 :(得分:2)

假设所需的行中只有一个点,这似乎可行。 [ grin ]如果变量$InStuff中有示例行,则返回不带“ Sometext”的两行。在其中...

$InStuff -notmatch ' [a-z]+\.'

输出...

CREATE OR REPLACE PACKAGE PKG_MASSIVE_SERVICE_AUTOMIC
CREATE OR REPLACE PACKAGE BODY PKG_MASSIVE_SERVICE_AUTOMIC

答案 1 :(得分:1)

仅匹配CREATE OR REPLACE PACKAGE ...而不包含{em> 的...行(文字).(仅由字母,数字,下划线和空白组成) ),您只需要确保您的正则表达式与整行匹配:

(Get-Content some.sql) -match '^CREATE\sOR\sREPLACE\sPACKAGE\s[\sa-z_0-9]+$'

请注意,我删除了A-Z,这是不需要的,因为PowerShell的-match运算符不区分大小写 -cmatch可用于区分大小写 )。

答案 2 :(得分:1)

从字面上看问题标题,这是一个negative lookahead (?!.*\..*)

的解决方案

将较长的样本存储在文件.\some.sql中,假设没有锚点 CREATE...的第一行-^-不在第一行开始

(Get-Content .\some.sql) -match "CREATE\sOR\sREPLACE\sPACKAGE\s(BODY )?(?!.*\..*)"

产生此输出。

CREATE OR REPLACE PACKAGE PKG_MASSIVE_SERVICE_AUTOMIC
 CREATE OR REPLACE PACKAGE BODY PKG_MASSIVE_SERVICE_AUTOMIC