我有这样的文字:
; Robert ( #Any kind of character here# ) #Any kind of character here#;
John ( #Any kind of character here# )
因此,为了查看文本是否像Robert(...)一样结束,或者像使用Python中的正则表达式那样约翰(...),我使用类似的东西:
if re.search(r'[;\s+]Robert\s*[(].*[)]\s*$', text, re.DOTALL) is not None:
# Some code here
elif re.search(r'[;\s+]John\s*[(].*[)]\s*$', text, re.DOTALL) is not None:
# Some code here
问题在于,由于括号内可能有任何内容(甚至更多对开括号括号),我使用带有选项DOTALL的de dot,因此它运行到最后一个括号并找到' Robert (...)'每次虽然正确答案是约翰(...)'。
那么,我怎样才能解决这个问题并让它停在正确的括号内找到约翰'?
答案 0 :(得分:0)
re模块没有处理嵌套括号的功能,但是regex module有一个递归功能(以及更多):
import regex
s='''; Robert ( #Any kind of character here# ) #Any kind of character here#;
John ( #Any kind of character here# )'''
pat = r'(?r);\s*(Robert|John)\s*\(([^()]*+(?:\((?2)\)[^()]*)*+)\)\s*$'
m = regex.search(pat, s)
if m is not None:
if m.group(1) == 'Robert':
print('Robby')
else:
print('Johnny')
模式细节:
(?r) # reverse search modifier: search from the end of the string
;\s* #
(Robert|John) \s* # capture group 1
\(
( # capture group 2
[^()]*+ # all that isn't a bracket
(?:
\( (?2) \) # recursion with the capture group 2 subpattern
[^()]*
)*+
)
\) \s* $
答案 1 :(得分:0)
免责声明,这篇文章'工作'但不应该使用
首先,正如我之前评论的那样,正则表达式并不意味着递归,如果你想要干净利落地解决这个问题,你可能需要使用像pyparsing这样的模块。
如果你仍然非常想要用脚射击并使用正则表达式做一些它不打算做的事情,你可以使用regex
模块。卡西米尔的一项技术用完全正常的递归正则表达式精美地解释了。我不建议这样做,但我无法判断你当前的位置。
但是,嘿,为什么当你可以用它完整的腿时拍自己的脚?当然只使用内置的re
模块:D因此,如果没有进一步的延迟,可以做出无法维护的混乱并无限期地保持工作,直到他们完全重写您正在制作的任何内容:< / p>
import re
n = 25 # level of nesting allowed, must be specified due to python regex not being recursive
parensre = r"\([^()]*" + r"(?:\([^()]*" * n + r"[^()]*\))?" * n + r"[^()]*\)"
robertre = re.compile(r"Robert\s*" + parensre, re.M | re.S)
johnre = re.compile(r"John\s*" + parensre, re.M | re.S)
tests = """
Robert (Iwant(to(**doRegexMyWay(hithere) * 8) / 3) + 1) ; John (whatever())
John(I dont want to anymore())
"""
print robertre.findall(tests) # outputs ['Robert (Iwant(to(**doRegexMyWay(hithere) * 8) / 3) + 1)']
print johnre.findall(tests) # outputs ['John (whatever())', 'John(I dont want to anymore())']
你当然可以混合和组合各个部分,parensre
是你已经崩溃的沙堡的基石。诀窍是创建n(默认为25个)非捕获组,所有组都嵌套在一起。单个组的结构类似于(
非括号捕获组非括号)
品尝它产生的正则表达式:
\([^()]*(?:\([^()]*(?:\([^()]*(?:\([^()]*(?:\([^()]*(?:\([^()]*(?:\([^()]*(?:\([^()]*(?:\([^()]*(?:\([^()]*(?:\([^()]*(?:\([^()]*(?:\([^()]*(?:\([^()]*(?:\([^()]*(?:\([^()]*(?:\([^()]*(?:\([^()]*(?:\([^()]*(?:\([^()]*(?:\([^()]*(?:\([^()]*(?:\([^()]*(?:\([^()]*(?:\([^()]*(?:\([^()]*[^()]*\))?[^()]*\))?[^()]*\))?[^()]*\))?[^()]*\))?[^()]*\))?[^()]*\))?[^()]*\))?[^()]*\))?[^()]*\))?[^()]*\))?[^()]*\))?[^()]*\))?[^()]*\))?[^()]*\))?[^()]*\))?[^()]*\))?[^()]*\))?[^()]*\))?[^()]*\))?[^()]*\))?[^()]*\))?[^()]*\))?[^()]*\))?[^()]*\))?[^()]*\)
TL; DR请不要尝试使用re