Python 如何匹配整个回溯消息并且不提前停止使用regex
下面是python代码:Python 如何匹配整个回溯消息并且不提前停止使用regex,python,regex,Python,Regex,下面是python代码: st = """ Traceback (most recent call last): File "/builder_task.py", line 279, in do_one_task raise RecoverableBuildException("test error") common.exceptions.BuildException: test error """ st2 = """ Traceback (most recent call las
st = """
Traceback (most recent call last):
File "/builder_task.py", line 279, in do_one_task
raise RecoverableBuildException("test error")
common.exceptions.BuildException: test error
"""
st2 = """
Traceback (most recent call last):
File "/builder_task.py", line 279, in do_one_task
raise RecoverableBuildException("test error")
common.exceptions.BuildException
"""
EXCEPTION_PATTERN = re.compile(
r"Traceback \(most recent call last\):(?s).*?([\w\.]*(?:Exception|Error))(: .*?\n)?"
)
ex_match = EXCEPTION_PATTERN.findall(st)
ex_match2 = EXCEPTION_PATTERN.findall(st2)
我希望匹配整个stacktrace和capture
(“common.exceptions.BuildException”,“:测试错误”)
用于st
st2的(“common.exceptions.BuildException”,”)
然而,它从一开始就与“raiserecoverablebuildexception”匹配,并捕获了
('RecoverableBuildException','')
对于st和('',)
对于st2我首先要了解,任何合适的用户定义的异常类都以“Exception”或“Error”结尾(好的,看起来您已经记下了)。现在,您可以使用re.search
>>> import re
>>> re.search(r'(?<=\n)(.*?(?:Exception|Error)):\s*(.*?)(?=\n|$)', st).groups()
('common.exceptions.BuildException', 'test error')
>>重新导入
>>>re.search(r’(?我首先要了解,任何合适的用户定义异常类都以“Exception”或“Error”结尾(好的,看起来您已经有了这个)。现在,您可以使用re.search
>>> import re
>>> re.search(r'(?<=\n)(.*?(?:Exception|Error)):\s*(.*?)(?=\n|$)', st).groups()
('common.exceptions.BuildException', 'test error')
>>重新导入
>>>重新搜索(r’(?您只获得第一个捕获组,因为您匹配了非贪婪的*?
,然后在一个匹配零次或多次的组中捕获一个单词字符或一个点[\w\.]*
后跟异常或错误。第一次匹配的时间是RecoverableBuildException
,并在组1中捕获
下面是(:.*?\n)?
但在匹配第一组后,没有要匹配的:
,因此第二组不匹配
您可以使用::
Traceback\(最近一次调用last\):(?:\n.*)+?\n(.*(?:异常|错误):)\s*(.+)
这将符合:
Traceback\(最近一次调用last\):
按字面意思匹配
(?:\n.*)+?
在匹配换行符的非捕获组中重复,后跟0+次任意字符
\n(.*(?:异常|错误):)匹配换行符和capturinggroup 0+字符非贪婪,然后匹配错误异常,后跟
:`
\s*
匹配0+空格字符
(.+)
捕获组1+乘以任意字符
例如:
EXCEPTION_PATTERN = re.compile(
r"Traceback \(most recent call last\):(?:\n.*)+?\n(.*?(?:Exception|Error):)\s*(.+)"
)
ex_match = EXCEPTION_PATTERN.findall(st)
print(ex_match) # [('common.exceptions.BuildException:', 'test error')]
您只获得第一个捕获组,因为您匹配了非贪婪的*?
,然后在一个匹配零次或多次的组中捕获一个单词字符或一个点[\w\.]*
,后跟异常或错误。将匹配的第一次是可恢复的BuildException
,并捕获到组1
下面是(:.*?\n)?
但在匹配第一组后,没有要匹配的:
,因此第二组不匹配
您可以使用::
Traceback\(最近一次调用last\):(?:\n.*)+?\n(.*(?:异常|错误):)\s*(.+)
这将符合:
Traceback\(最近一次调用last\):
按字面意思匹配
(?:\n.*)+?
在匹配换行符的非捕获组中重复,后跟0+次任意字符
\n(.*(?:异常|错误):)匹配换行符和capturinggroup 0+字符非贪婪,然后匹配错误异常,后跟
:`
\s*
匹配0+空格字符
(.+)
捕获组1+乘以任意字符
例如:
EXCEPTION_PATTERN = re.compile(
r"Traceback \(most recent call last\):(?:\n.*)+?\n(.*?(?:Exception|Error):)\s*(.+)"
)
ex_match = EXCEPTION_PATTERN.findall(st)
print(ex_match) # [('common.exceptions.BuildException:', 'test error')]
<>你的正则表达式中间的“?”是非贪婪的:它将尽可能少地满足表达式。因为“(?:?\n)?”是可选的(这就是最终的“?”:匹配0或1的父括号中的内容)在“RealVabueBueDebug”结尾处的“异常”满足表达式。
有两种方法可以获得您想要的结果:
- 从中间的“.*”中移除“?”,使其变得贪婪,使其尽可能匹配。
- 将“:”移到最后一个括号之前,使表达式以“|Error”):(.*?\n)结尾(甚至只是删除“:”之外的所有内容,使其以“|Error”):”结尾)
在正则表达式中间的“?”是非贪婪的:它将尽可能地匹配以满足表达式。因为“(:.?\n)?”是可选的(这就是最后的“?”的作用:匹配参数中的0或1),所以“RecoverableBuildException”结尾的“Exception”满足表达式
有两种方法可以获得您想要的结果:
- 从中间的“.*”中移除“?”,使其变得贪婪,使其尽可能匹配。
- 将“:”移到最后一个括号之前,使表达式以“|Error”):(.*?\n)结尾(甚至只是删除“:”之外的所有内容,使其以“|Error”):”结尾)
清晰有效,谢谢!我还学习了如何在不使用(?s)模式的情况下匹配多行。后续:如果ex name后没有“:test error”怎么办(请参见编辑问题中的我的st2)?在这种情况下,您的解决方案不匹配。谢谢@第四bird@Lee例如,您可以将错误消息结构与由点分隔的单词字符匹配Traceback\(最近一次调用last\):(?:\n.*)+?\n(\w+(?:\。\w+*)。\w+。(?:Exception | error)\b)(?::\s*(*)?
@如果您未选中已应答的标记。我上一个例子对你不起作用吗?是的,第一个不起作用。现在,你的评论中的一个起作用了。谢谢,一切正常,谢谢!我还学习了如何在不使用(?s)模式的情况下匹配多行。后续:如果ex name后没有“:test error”怎么办(请参见编辑问题中的我的st2)?在这种情况下,您的解决方案不匹配。谢谢@第四bird@Lee例如,您可以将错误消息结构与由点分隔的单词字符匹配Traceback\(最近一次调用last\):(?:\n.*)+?\n(\w+(?:\。\w+*)。\w+。(?:Exception | error)\b)(?::\s*(*)?
@如果您未选中已应答的标记。我上一个例子对你不起作用吗?是的,第一个不起作用。现在,你的评论中的一个起作用了。谢谢