Как использовать Lookahead на Regex - PullRequest
0 голосов
/ 06 апреля 2019

У меня есть сценарий sql для создания или замены пакетов в Oracle, и мне нужно проверить, находится ли запрос в синтаксисе схемы, например, «пользователь». «Объект», для таких инструкций, как «Создать» или «Изменить таблицу».Регулярное выражение простое, но в случае создания 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 

Вторая и четыре строки являются единственно действительными, как я могу сопоставить только недействительные запросы, т.е. строки 1 и 3?

Я пыталсяиспользовать:

^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 ]

2 голосов
/ 06 апреля 2019

при условии, что в строке разыскивается только ОДНА точка, похоже, это работает. [ 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 голос
/ 06 апреля 2019

Буквально взяв название вопроса, решение с отрицательным взглядом (?!.*\..*)

Если ваш более длинный сэмпл хранится в файле .\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
1 голос
/ 06 апреля 2019

Чтобы соответствовать только CREATE OR REPLACE PACKAGE ... строкам, где ... содержит , а не содержит (литерал) . (будучи составленным только из букв, цифр, подчеркиваний и пробелов), вам просто нужно сделать убедитесь, что ваше регулярное выражение соответствует полной строке :

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

Обратите внимание, что я удалил A-Z, который не нужен, потому что оператор -match в PowerShell нечувствителен к регистру (-cmatch может использоваться для чувствительного к регистру * совпадение).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...