如何提取字符串中的最后一组括号

时间:2015-04-10 22:30:53

标签: python regex

我有很长的字符串列表,我需要捕获最后一个或多个字符。对于简单字符串"axa""lmn"str[0]有效。

有些情况下,最后一个字符可以是2,例如字符串“qa(n|m), 最后一个字符可以是nm。所以我需要捕获字符串中的最后一组括号并获取其中的所有内容。 在这种情况下,re.search('\((.*?)\)',s).group(1)给出内容。但是,如果该字符串有两组括号,则它不起作用。

例如:if str= "aaa(2)bbb(n|m)",我只需要'n|m'

感谢任何帮助。

3 个答案:

答案 0 :(得分:3)

假设子串总是在最后,你可以找到最右边的(并切片到结尾-1:

s = "aaa(2)bbb(n|m)"

print(s.rstrip("*")[s.rfind("(")+1:-1])
n|m

或者使用re只需使用findall并获取最后一个元素:

import re

print(re.findall('\((.*?)\)',s)[-1])

rstrip会删除*,如果它作为字符串的结尾,或者什么都不做。

In [24]: s = "ee(1)bb(aaa|bbb)*"
In [25]: print(s.rstrip("*")[s.rfind("(")+1:-1])
aaa|bbb
In [26]: print(re.findall('\((.*?)\)',s)[-1])
aaa|bbb    
In [27]: s = "ee(1)bb(aaa|bbb)"    
In [28]: print(re.findall('\((.*?)\)',s)[-1])
aaa|bbb    
In [29]: print(s.rstrip("*")[s.rfind("(")+1:-1])
aaa|bbb

答案 1 :(得分:2)

rpartition()partition()

>>> "aaa(2)bbb(n|m)".rpartition('(')[2].partition(')')[0]
'n|m'

如果右括号始终是字符串中的最后一个字符,则可以将.partition(')')[0]替换为[:-1]

>>> "aaa(2)bbb(n|m)".rpartition('(')[2][:-1]
'n|m'

答案 2 :(得分:1)

您可以使用纯正则表达式方法使用此正则表达式执行此操作:

\(([^)]+)\)[^)]*\Z

Demo

在Python中:

>>>> s=''.join(["aaa(2)bbb(n|m{})".format(i) for i in range(5001)])

(使长字符串aaa(2)bbb(n|m0)最多为aaa(2)bbb(n|m5000)

>>> import re
>>>> re.search(r'\(([^)]+)\)[^)]*\Z', s).group(1)
'n|m5000'

优点是只进行了一次匹配,而不是像re.findall那样构建每个匹配的完整列表。

锚定匹配通常也更快。

如果你想要更快,但是以可读性为代价,你可以这样做:

  1. 反转字符串;
  2. 匹配第一组内括号;
  3. 反转比赛。
  4. 演示:

    >>>> re.search(r'^[^)]*\)([^(]+)\(', s[::-1]).group(1)[::-1]
    'n|m5000'
    

    计时:

    >>> import timeit
    >>> timeit.timeit("re.findall('\((.*?)\)',s)[-1]", setup="from __main__ import s, re", number=1000)
    2.9381589889526367000
    >>> timeit.timeit("re.search(r'\(([^)]+)\)[^)]*\Z', s).group(1)", setup="from __main__ import s, re", number=1000)
    1.588352918624878
    >>> timeit.timeit("re.search(r'^[^)]*\)([^(]+)\(', s[::-1]).group(1)[::-1]", setup="from __main__ import s, re", number=1000)
    0.27100610733032227
    

    你可以看到反向字符串方法比其他两种方法快10倍或6倍......