2

我必须在 python 中用正则表达式解析一个日志 txt 文件。这是一个 txt 示例(名为file):

20/01/18,08:11 - 彼得:早上好

你好吗?

彼得 20/01/18,09:00 - 卡罗琳:我很好,谢谢。你?

20/01/18,09:01 - 彼得:好

几天前我遇到了一些问题。

现在我很开心

你在工作吗?

20/01/18,09:02 - Caroline:不,我必须去超市买蔬菜

20/01/18,09:12 - 彼得:太好了!

你现在在哪里?

我试图用这个正则表达式解析整个文本:

f = open(file, 'r', encoding='utf-8')
texts=re.findall('(\d+/\d+/\d+, \d+:\d+\d+) - (.+?): (.*)',f.read())
f.close()

df= pd.DataFrame(texts,columns=['data','name','text'])

但是,在 python 中匹配一个或多个换行符时我遇到了问题(例如 Peter 在 09:01 的文本)。我也尝试在https://regex101.com/上寻找可能的解决方案,但没有成功。

你能帮我吗?

4

2 回答 2

2

如果要匹配以下文本,直到新行开头的下一个日期,您可以使用负前瞻匹配所有不以类似日期模式开始的行:

(\d+/\d+/\d+, \d+:\d+\d+) - (.+?): (.*(?:\r?\n(?!\d+/\d+/\d).*)*)

关于最后一部分(.*(?:\r?\n(?!\d+/\d+/\d).*)*)

  • (捕获组 3
    • .*匹配除换行符以外的任何字符 0+ 次
    • (?:非捕获组
      • \r?\n 匹配新行
      • (?!\d+/\d+/\d).*断言右边的不是日期格式
    • )*关闭非捕获组并重复 0+ 次
  • )关闭组

正则表达式演示

于 2019-10-24T15:46:43.363 回答
0

默认情况下,.不会匹配换行符。您需要使用 DOTALL 模式使其匹配换行符:

re.findall('(\d+/\d+/\d+, \d+:\d+\d+) - (.+?): (.*)', f.read(), re.DOTALL)

有用:

>>> import re
>>> s="""
... 20/01/18, 09:01 - Peter: Good
... 
... I had some problems few days ago.
... 
... Now I am happy
... 
... Are you working?"""
>>> re.findall('(\d+/\d+/\d+, \d+:\d+\d+) - (.+?): (.*)', s, re.DOTALL)
[('20/01/18, 09:01', 'Peter', 'Good\n\nI had some problems few days ago.\n\nNow I am happy\n\nAre you working?')]
>>> _

但是,这并不能解决匹配整个其余文本的问题!

请参阅@the-fourth-bird 的答案以获得真正的解决方案。

其他。更明确的处理方法是逐行读取文件,并检查一行是否是续行。

rx = re.compile('^(\d+/\d+/\d+, \d+:\d+\d+) - (.+?): (.*)$') # Note the ^.
texts = []
for line in input_file:  # Files iterate line by line.
  new_match = rx.match(line)
  if new_match:
    texts.append(list(new_match.groups()))  # We want a list
  else:
    # We have a continuation line; append it to the last item of group.
    last = texts[-1]
    last[-1] += line  # Update in-place.

这可能更容易推理。

于 2019-10-24T15:44:19.590 回答