#regex #python-2.7
#регулярное выражение #python-2.7
Вопрос:
CREATE TABLE "TEST_OWNER"."TEST_NOTIFY"
(
"test1" NUMBER,
"test2" VARCHAR2 ( 200 BYTE ) ,
"test3" DATE,
"test4" NUMBER,
"test5" NUMBER(5, 6 ),
"test6" TIMESTAMP (0 ) WITH TIME ZONE,
"test7" VARCHAR2(200 BYTE )
) SEGMENT CREATION IMMEDIATE
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
NOCOMPRESS LOGGING
STORAGE(INITIAL 4545 NEXT 56565 MINEXTENTS 1 MAXEXTENTS 898989
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "TEST_TABLESPACE"
;
ALTER TABLE MD_CMPLY_PII_MASTER ADD SKIP_FLAG CHAR(1 BYTE);
из приведенного выше примера я хочу сопоставить закрывающие скобки, которые не подпадают под приведенные ниже условия.
- оно не должно совпадать с закрывающей скобкой в строках типа
"test2" VARCHAR2 ( 200 BYTE),
"test5" NUMBER(5, 6 ),
"test6" TIMESTAMP (0 ) WITH TIME ZONE,
- ИЗМЕНИТЬ ТАБЛИЦУ MD_CMPLY_PII_MASTER ДОБАВИТЬ СИМВОЛ SKIP_FLAG (1 БАЙТ);
т.е. при сопоставлении следует избегать всех закрывающих круглых скобок, которые являются частью длины или точности.
Из приведенного выше примера оно должно соответствовать только закрывающим скобкам следующих строк,
) SEGMENT CREATION IMMEDIATE
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
Я создал регулярные выражения, которые обнаруживают закрывающие скобки, которых следует избегать. Они:
-
для обнаружения закрывающих скобок
"test2" VARCHAR2 ( 200 BYTE ) ,
строки:(?=(s{0,}d s{0,}w s{0,}()))
https://regex101.com/r/va73vG/1
-
для обнаружения закрывающих скобок
"test5" NUMBER(5, 6 ),
строки:(?=d s{0,}()))
https://regex101.com/r/zDbGUa/1
Я попытался объединить два вышеупомянутых регулярных выражения, но оно по-прежнему соответствует всем закрывающим скобкам:
(?=()))(?!((s{0,}d s{0,}w s{0,})))(?!(d s{0,})))
https://regex101.com/r/Mtykby/1
Как получить желаемый результат?
обновлено
регулярное выражение, на которое дан ответ, не работает для приведенного ниже оператора ALTER
ALTER TABLE test ADD SKIP_FLAG CHAR(1 BYTE);
Я обновил входные данные в вопросе.какую модификацию я должен сделать, чтобы согласовать условия с новыми входными данными?
Ответ №1:
Вы могли бы использовать логику сопоставления закрывающих круглых скобок, за которыми следует только равное количество открывающих и закрывающих круглых скобок. Когда за ними следует больше закрывающих, чем открывающих скобок, их не следует сопоставлять:
$
Должен обозначать конец ввода, а не конец строки, поэтому не используйте m
модификатор.
Выше фактически найдены закрывающие круглые скобки, которые сами по себе не содержатся во внешних круглых скобках.
Альтернатива
Если входные данные могут быть без внешних круглых скобок (как в alter table
примере, добавленном к вашему вопросу), то вышеуказанное не будет работать корректно. Вместо этого вы могли бы сопоставлять целые выражения в круглых скобках, пропуская вложенные выражения, которые следует игнорировать, а затем поместить закрывающую скобку в группу захвата.
Вот как это могло бы работать в Python, учитывая строку str
:
import re
results = re.finditer(r"(s*[^sd](?:(s*d[^()]*)|(?:())|.))*", str, re.DOTALL)
for match in results:
pos = match.start(1) # position of the closing parenthesis
print "pos = ", pos, ", near: ...", str[max(0,pos-10):pos 1]
Комментарии:
1. В приведенном выше регулярном выражении, как я могу избежать выбора следующей закрывающей скобки в следующем операторе? ALTER TABLE test ДОБАВИТЬ символ col1 (1 БАЙТ);
2. Смотрите дополнение к ответу.