使用python re.findall收集出席列表
这里我们有一个缩放聊天历史记录,我想从中提取所有学生ID,例如38150002和ID所有者的姓名(例如smith示例) 我用re.findall成功地用一组模式提取了学生id使用python re.findall收集出席列表,python,Python,这里我们有一个缩放聊天历史记录,我想从中提取所有学生ID,例如38150002和ID所有者的姓名(例如smith示例) 我用re.findall成功地用一组模式提取了学生id lst = re.findall('\d\d-\d+', ex) #for id like 40-250233 问题是如何提取学生id后面的姓名?有很多方法,但这里有一个简单的方法,使用拆分和联接,假设: 冒号在文件中作为分隔符保持不变 学生ID后的所有内容均指学生姓名 代码如下,应用于一行: row_string =
lst = re.findall('\d\d-\d+', ex) #for id like 40-250233
问题是如何提取学生id后面的姓名?有很多方法,但这里有一个简单的方法,使用拆分和联接,假设:
row_string = "17:00:44 From Smith Example : 38150002 Smith Example"
ID = row_string.split(':')[3].split(' ')[1] # '38150002'
name = " ".join(row_string.split(':')[3].split(' ')[2:]) #'Smith Example'
输入:
输出:
[(': ', '38150002', ' Smith Example\n17'), (': ', '41050002', ' Smith Middle Example\n17'), (': ', '37-191129', ' Smith One Example\n17'), (': ', '31-086612', ' Smith Example\n17'), (': ', '40-250233', ' Smith Example\n17'), (': ', '38129055', ' Smith Example\n17'), (': ', '38-129055', ' Smith Example Joe')]
在这里,您可以得到与您给出的示例相匹配的两种模式。
对于每个匹配的模式,输出基本上包含3个部分-第一部分是
:
,第二部分是ID
,这是您给定的两个模式(如果您想匹配更多的模式,您应该根据需要更改正则表达式,不能以通用方式编写正则表达式),第三部分是ID之后的整个字符串
(如果您只想捕获最多第二个空格或第三个空格字符,则还应自定义此项)假设您给出了确切的结构,您可以使用此正则表达式:
\d\d:\d\d:\d\d.*:\s*([\d-]+)\s*(.*)$
我将ID和名称放在捕获组中,因此使用findall
将得到一个很好的结果。例如:
重新导入
s=“”17:00:44来自史密斯示例:38150002史密斯示例\n
17:00:54来自史密斯示例:41050002史密斯中间示例\n
17:01:04自史密斯示例:37-191129史密斯示例\n
17:01:12自史密斯示例:31-086612史密斯示例\n
17:01:20自史密斯示例:40-250233史密斯示例\n
17:01:33来自史密斯示例:38129055史密斯示例\n
17:01:39来自史密斯示例:38-129055史密斯示例乔\n“”
打印(re.findall(r'\d\d:\d\d:\d\d.*:\s*([\d-]+)\s*(*)$,s,re.M))
将提供:
[('38150002', 'Smith Example'),
('41050002', 'Smith Middle Example'),
('37-191129', 'Smith One Example'),
('31-086612', 'Smith Example'),
('40-250233', 'Smith Example'),
('38129055', 'Smith Example'),
('38-129055', 'Smith Example Joe')]
请注意,如果您逐行迭代文件,则不需要该标志。使用以下命令提取ID和名称(请随意优化与regex
\w+(?:[]\w+
匹配的名称,以获得更好的控制):
>>关于findall('\d\d-\d+[]\w+(?:[]\w+',ex)
['37-191129史密斯一例','31-086612史密斯一例','40-250233史密斯一例','38-129055史密斯一例']
如果仅需要名称,请使用非捕获组(?:)
忽略ID部分,并将名称放入()
:
>>关于findall('(?:\d\d-\d+[])(\w+(?:[]\w+),例如)
['Smith One Example'、'Smith Example'、'Smith Example'、'Smith Example'、'Smith Example Joe']
顺便说一句,您还可以将ID和名称捕获为元组:
>>关于findall('(\d\d-\d+[])(\w+(?:[]\w+),ex)
[('37-191129','Smith One Example'),('31-086612','Smith Example'),('40-250233','Smith Example'),('38-129055','Smith Example Joe')]
这似乎没有回答这个问题。你的代码没有返回与ID相关联的全名-它只返回姓氏。此外,你也没有返回没有连字符的ID。嘿,谢谢你的回答。我只是展示了一个使用re.findall收集所有ID的示例。但正是这些名称让我困惑,因为学生们没有结束以不同的模式输入他们的名字。我已经更新了。应该适用于你给出的模式。非常感谢你的回答。“学生ID后的所有内容都指向学生名字”似乎是一个很好的方法,因为不同的学生倾向于以不同的模式输入他们的名字。有了你的答案,我可以收集ir名称,而不必担心如何输入名称。(例如,有些人只是在名字和姓氏之间没有空格)
\d\d:\d\d:\d\d.*:\s*([\d-]+)\s*(.*)$
[('38150002', 'Smith Example'),
('41050002', 'Smith Middle Example'),
('37-191129', 'Smith One Example'),
('31-086612', 'Smith Example'),
('40-250233', 'Smith Example'),
('38129055', 'Smith Example'),
('38-129055', 'Smith Example Joe')]