簡體   English   中英

Python 正則表達式識別字符串中的括號對; 除非括號在方括號中?

[英]Python regular expression to identify parentheses pairs in a string; unless the parentheses are in a squared bracket?

我有一個看起來像這樣的字符串:

[object]-ABGF-[A-BEC(2)]-LRPG-[object]
ABCDEFGHDGSASDASR-(typ1)-ASDHASDUASIUDHAS-[object]
[object]-RLC(1)-C(2)-GF-[obj]-KSASDASD-[obj3]-ASD-[object]
[object3]-RLC(1)-C(2)-GF-[Hyp]-KSCRSRQCK-[Hyp]-HRCC-[amide]
ABCDEFGHIJK(1)-GHGSHS(2)-ABCDE
ABCDD(1)-ASDASDASD(1)-ASBFIFD
ASDASDASD(1)-ASDASADJASJS(2)-ERASDASD

目的是:我想找到字符串,其中有帶數字的括號(),但數字不是成對的(即兩組括號中沒有兩個相同的數字),除非括號本身在方括號。

例如,我想從上面的列表中識別出的序列是:

[object]-RLC(1)-C(2)-GF-[obj]-KSASDASD-[obj3]-ASD-[object]
[object3]-RLC(1)-C(2)-GF-[Hyp]-KSCRSRQCK-[Hyp]-HRCC-[amide]
ABCDEFGHIJK(1)-GHGSHS(2)-ABCDE
ASDASDASD(1)-ASDASADJASJS(2)-ERASDASD

因為括號中的每個數字都應該成對出現在序列中,所以在這種情況下應該有兩個(1),而這些有一個(1)和一個(2)。

但不應返回以下序列,因為單括號位於方括號中:

[object]-ABGF-[A-BEC(2)]-LRPG-[object] (because it's in a square bracket)

我不能對數字進行硬編碼,因為理論上這應該檢查無限數量的對,例如,如果序列是:

AVDD(1)-ASDAS(2)-ASDAFJF(3)-ASDAS(1)-ASGGG(2)

這也應該返回,因為 (3) 缺少一對,即使 1 和 2 正確配對。

但如果順序是:

ASDHD(9)-ASDJAS(9) 

這不會被返回,因為那是一對括號(括號不在括號中)

我寫了這段代碼:

circle_pattern = re.compile(r'\(([a-z0-9]+)\)')
if circle_regex:
x_list = ["(" + re.sub("\d", "x", i) + ")" for i in circle_regex]
check_if_even = dict(Counter(circle_regex))
for k,v in check_if_even.items():
       if v % 2 != 0:
                print(row)

返回:

[object]-ABGF-[A-BEC(2)]-LRPG-[object]
ABCDEFGHDGSASDASR-(typ1)-ASDHASDUASIUDHAS-[object]
[object]-RLC(1)-C(2)-GF-[obj]-KSASDASD-[obj3]-ASD-[object]
[object3]-RLC(1)-C(2)-GF-[Hyp]-KSCRSRQCK-[Hyp]-HRCC-[amide]
ABCDEFGHIJK(1)-GHGSHS(2)-ABCDE
ASDASDASD(1)-ASDASADJASJS(2)-ERASDASD

但是有人可以告訴我如何修改這段代碼,所以它不會返回第一個序列,因為在那種情況下 (2) 在方括號中?

您可以使用 2 次否定前瞻來排除不應匹配的內容。

^(?!.*?\[[^][()]*\([^()]*\))(?!.*?\((\d+)\).*?\1).+

模式匹配

  • ^字符串開頭
  • (?!負前瞻
    • .*?\[[^][()]*\([^()]*\) []之間匹配()
  • )關閉前瞻
  • (?!負前瞻
    • .*?\((\d+)\).*?\1匹配括號內相同數字的 2 次
  • )關閉前瞻
  • .+匹配任何字符的 1+ 次

正則表達式演示| Python 演示

例子

import re

regex = r"^(?!.*?\[[^][()]*\([^()]*\))(?!.*?\((\d+)\).*?\1).+"

s = ("[object]-ABGF-[A-BEC(2)]-LRPG-[object]\n"
    "ABCDEFGHDGSASDASR-(typ1)-ASDHASDUASIUDHAS-[object]\n"
    "[object]-RLC(1)-C(2)-GF-[obj]-KSASDASD-[obj3]-ASD-[object]\n"
    "[object3]-RLC(1)-C(2)-GF-[Hyp]-KSCRSRQCK-[Hyp]-HRCC-[amide]\n"
    "ABCDEFGHIJK(1)-GHGSHS(2)-ABCDE\n"
    "ABCDD(1)-ASDASDASD(1)-ASBFIFD\n"
    "ASDASDASD(1)-ASDASADJASJS(2)-ERASDASD")

matches = re.finditer(regex, s, re.MULTILINE)
for matchNum, match in enumerate(matches, start=1):
    print (match.group())

Output

ABCDEFGHDGSASDASR-(typ1)-ASDHASDUASIUDHAS-[object]
[object]-RLC(1)-C(2)-GF-[obj]-KSASDASD-[obj3]-ASD-[object]
[object3]-RLC(1)-C(2)-GF-[Hyp]-KSCRSRQCK-[Hyp]-HRCC-[amide]
ABCDEFGHIJK(1)-GHGSHS(2)-ABCDE
ASDASDASD(1)-ASDASADJASJS(2)-ERASDASD

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM