正则表达式如何匹配某个结束括号,同时在python中排除其他

时间:2019-04-08 04:48:28

标签: regex 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);

在上面的示例中,我想匹配不属于以下条件的右括号。

  1. 它不应该与像这样的行中的右括号匹配
    • "test2" VARCHAR2 ( 200 BYTE),
    • "test5" NUMBER(5, 6 ),
    • "test6" TIMESTAMP (0 ) WITH TIME ZONE,
    • 更改表MD_CMPLY_PII_MASTER添加SKIP_FLAG CHAR(1 BYTE);

即,在匹配时必须避免所有长度或精度的右括号。

在上面的示例中,它应该仅与以下各行的右括号匹配,

  • ) 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);

我已经更新了问题中的输入数据。我该怎么做才能使条件与新输入数据相匹配?

链接:https://regex101.com/r/4Cu2wF/4

1 个答案:

答案 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]