问题描述
我正在尝试使用 Python 的 re 模块解析 .txt 文件中某个应用程序中的一些对话,但是尽管在用于文件样本时处理 regex101,但当我使用它时它无法正常工作打开文件并实际尝试解析它。
txt 文件的结构是 dd/mm/yyyy hh:mm - Message Author: message text\n
,我试图只获取 Name: message \n
部分。我正在使用以下模式 (?<=\d{2}\/\d{2}\/\d{4}\s\d{2}:\d{2}\s\-\s)(.*:.*$)
。我的代码看起来或多或少如下:
buffer = open(file,'r',encoding = 'UTF-8').read()
pattern = re.compile(r'(?<=\d{2}\/\d{2}\/\d{4}\s\d{2}:\d{2}\s\-\s)(.*:\s)(.*$)')
matches = re.findall(pattern,buffer)
不过,正如标题所说, findall 返回并为空列表,我不知道为什么。以下示例在 regex101 上按预期工作:
20/04/2021 09:54 - Person 1: this is an example text. Will it match?
20/04/2021 09:54 - Person 2: I think it does.
解决方法
Lookarounds 是“昂贵的”。更好地匹配您想要的内容并捕捉有趣的部分。
也就是说,您可能会使用更简单的表达方式:
int main() {
return 123;
}
,
亲吻:去掉$
。它匹配字符串的结尾。您需要匹配行尾,re.M
在这里可能会有所帮助。但删除 $
更简单。
(?<=\d{2}\/\d{2}\/\d{4}\s\d{2}:\d{2}\s\-\s)(.*:\s)(.*)
但即使是“亲吻”者:如果您在表达式中使用捕获组,则不需要后视或转义斜线,因为 re.findall
会返回捕获的字符串。
使用
pattern = re.compile(r'\b\d{2}/\d{2}/\d{4}\s*\d{2}:\d{2}\s*-\s*(?P<name>.*):\s*(?P<message>.*)')
with open(file,'r',encoding = 'UTF-8') as buffer:
matches = [match.groupdict() for match in pattern.finditer(test_str)]
说明
--------------------------------------------------------------------------------
\b the boundary between a word char (\w) and
something that is not a word char
--------------------------------------------------------------------------------
\d{2} digits (0-9) (2 times)
--------------------------------------------------------------------------------
/ '/'
--------------------------------------------------------------------------------
\d{2} digits (0-9) (2 times)
--------------------------------------------------------------------------------
/ '/'
--------------------------------------------------------------------------------
\d{4} digits (0-9) (4 times)
--------------------------------------------------------------------------------
\s* whitespace (\n,\r,\t,\f,and " ") (0 or
more times (matching the most amount
possible))
--------------------------------------------------------------------------------
\d{2} digits (0-9) (2 times)
--------------------------------------------------------------------------------
: ':'
--------------------------------------------------------------------------------
\d{2} digits (0-9) (2 times)
--------------------------------------------------------------------------------
\s* whitespace (\n,and " ") (0 or
more times (matching the most amount
possible))
--------------------------------------------------------------------------------
- '-'
--------------------------------------------------------------------------------
\s* whitespace (\n,and " ") (0 or
more times (matching the most amount
possible))