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,
即,在匹配时必须避免所有长度或精度的右括号。
在上面的示例中,它应该仅与以下各行的右括号匹配,
) 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);
我已经更新了问题中的输入数据。我该怎么做才能使条件与新输入数据相匹配?
答案 0 :(得分:1)
您可以使用匹配的结束括号的逻辑,该括号后面只跟相等数量的开始和结束括号。如果后面的结束符比右括号多,则不应该匹配:
$
应该表示输入的结尾,而不是行的结尾,所以不要使用m
修饰符。
上面实际上找到了不包含在外括号中的右括号。
如果输入中可能没有外部括号(如在您的问题中添加的alter table
示例中),则以上内容将无法正常工作。相反,您可以在括号中匹配整个表达式,跳过应忽略的子表达式,然后将右括号放在捕获组中。
在给定字符串str
的情况下,这是在Python中的工作方式:
import re
results = re.finditer(r"\(\s*[^\s\d](?:\(\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]