通过Regex和Maxsplit拆分字符串会返回多个拆分



我有一个从聊天日志数据中提取的字符串列表,我正在努力寻找从语音内容中分离说话者的最佳方法。两个例子如下:

mystr = ['bob123 (5:09:49 PM): hi how are you', 
'jane_r16 (12/01/2020 1:39:12 A.M.) : What day is it today?']

请注意,虽然它们大致相似,但我需要说明一些风格上的差异(包括日期、句点、额外空格等(。我需要一种方法来将这些字符串和其他类似字符串标准化并拆分为以下列表:

mystrList = [['bob123','hi how are you'],['jane_r16','What day is it today']]

考虑到我不需要时间、数字或大多数标点符号,我认为合理的第一步是删除任何不必要的内容。这样做之后,我现在有了以下内容:

myCleanstr = ['bob(): hi how are you','janer() : What day is it today?']

这样做为每个字符串((:提供了一个非常独特的字符序列,它不太可能出现在同一字符串的其他地方。我随后的想法是将其用作去标记,使用Regex:来分割每个字符串

mystr_split = [re.split(r'()( ){,2}:', i, maxsplit=1, flags=re.I) for i in myCleanstr]

在这里,我的意图如下:

  • ()查找一个开后接一个闭括号符号的序列
  • ( ){,2}然后找到零个、一个或两个空白
  • :然后找到冒号符号

但是,在这两种情况下,我每个字符串都会收到三个对象。我得到了正确的演讲者ID和演讲内容。但是,在第一个字符串中,我得到了一个额外的NoneType Object,在第二个字符串中我得到了用一个空白填充的额外字符串。

我曾认为,包括maxsplit=1意味着这个过程将在找到第一个分割后结束,但事实并非如此。与其在我需要的内容上过滤我的结果,我更想了解它为什么会如此。

您可以使用

^(S+)s*([^()]*)s*:s*(.+)

或者,如果名称可以有空格:

^(S[^(]*?)s*([^()]*)s*:s*(.+)

请参阅regex演示#1和regex演示#2。正则表达式匹配:

  • ^-字符串的开头
  • (S+)-组1:任意一个或多个空白字符
  • [^(]*?-除了(字符之外,零个或多个字符,尽可能少
  • s*-零个或多个空白
  • (-一个(字符
  • [^()]*-除()之外的零个或多个字符
  • )-一个)字符
  • s*:s*-包含零个或多个空格的冒号
  • (.+)-第2组:除换行符之外的任何一个或多个字符,尽可能多(行的其余部分(

请参阅Python演示:

import re
result = []
mystr = ['bob123 (5:09:49 PM): hi how are you', 'jane_r16 (12/01/2020 1:39:12 A.M.) : What day is it today?']
for s in mystr:
m = re.search(r'^(S+)s*([^()]*)s*:s*(.+)', s)
if m:
result.append([z for z in m.groups()])
print(result)
# => [['bob123', 'hi how are you'], ['jane_r16', 'What day is it today?']]

最新更新