我正在尝试解析示例输入 test_string1 如下:
import re
TEST_STRING1 = """Using definitions from (yyyy/mm/dd): 2016/6/8
The following files are collected:
File: Test.exe
Source: Google
avping blob: 123123
Downloaded 3 Files
"""
def fun():
regex_exp = re.compile(r"File:\s(?P<File>[^\n\r\t]+?)[\n\r\t\s]*?"
r"Source:\s(?P<Source>.*)[^\w\d]*?"
r"avping\sblob:\s(?P<Avping_blob>([A-F]|[a-f]|[0-9]){6})")
result = {}
result['Files'] = []
for m in re.finditer(regex_exp, TEST_STRING1):
result['Files'].append(m.groupdict())
print result
if __name__ == "__main__":
fun()
上述代码的输出是:
{'Files': [{'Source': 'Google', 'File': 'Test.exe', 'Avping_blob': '123123'}]}
我想让输入中的一些字段可选,例如 avping blob: 喜欢
TET_STRING1 = """Using definitions from (yyyy/mm/dd): 2016/6/8
The following files are collected:
File: Test.exe
Source: Google
Downloaded 3 Files
"""
在上面的情况下,正则表达式返回不匹配。
我已将正则表达式更新为
regex_exp = re.compile(r"(File:\s(?P<File>[^\n\r\t]+?)[\n\r\t\s]*?"
r"Source:\s(?P<Source>.*)[^\w\d]*?"
r"|avping\sblob:\s(?P<Avping_blob>([A-F]|[a-f]|[0-9]){6}))")
在最后一行之前添加 |
。但随后它给出了 2 个与 OR 匹配的
{'Files': [{'Source': 'Google', 'File': 'Test.exe', 'Avping_blob': None}, {'Source': None, 'File': None, 'Avping_blob': '123123'}]}
我应该如何编写与两种输入类型(带和不带可选字段)模式匹配的正则表达式? 谢谢
最佳答案
您可以使用可选的非捕获组并使用 [^\w\d]*
贪婪版本:
(File:\s(?P<File>[^\n\r\t]+?)[\n\r\t\s]*?Source:\s(?P<Source>.*)[^\w\d]*(?:avping\sblob:\s(?P<Avping_blob>[A-Fa-f0-9]{6}))?)
请参阅regex demo
在您的代码中:
regex_exp = re.compile(r"(File:\s(?P<File>[^\n\r\t]+?)[\n\r\t\s]*?"
r"Source:\s(?P<Source>.*)[^\w\d]*" # <- Here ? is removed
r"(?:avping\sblob:\s(?P<Avping_blob>[A-Fa-f0-9]{6}))?)")
^^^ ^
此外,([A-F]|[a-f]|[0-9]){6})
=(?P<Avping_blob>[A-Fa-f0-9]{6})
.
关于用于模式匹配的 Python 正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37832701/