Python正则表达式,用于标识字符串中的括号对;除非括号在方括号内?

2024-04-28 21:13:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个字符串,如下所示:

[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)在方括号中吗


Tags: objifobject序列数字括号gfcircle
1条回答
网友
1楼 · 发布于 2024-04-28 21:13:23

您可以使用2个负lookahead来排除不应该匹配的内容

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

模式匹配

  • ^字符串的开头
  • (?!负前瞻
    • .*?\[[^][()]*\([^()]*\)匹配[]之间的{}
  • )关闭前瞻
  • (?!负前瞻
    • .*?\((\d+)\).*?\1在括号之间匹配相同数字的2倍
  • )关闭前瞻
  • .+匹配任何字符的1+倍

Regex demoPython demo

范例

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())

输出

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

相关问题 更多 >