Python—尝试捕获行的中间部分、正则表达式或拆分

Python—尝试捕获行的中间部分、正则表达式或拆分,python,regex,split,Python,Regex,Split,我有一个文本文件,里面有一些名字、电子邮件和其他东西。我想捕获电子邮件地址 我不知道这是拆分还是正则表达式问题 以下是一些示例行: [name]bill billy [email]bill.billy@hotmail.com [dob]01.01.81 [name]mark hilly [email]mark.hilly@hotmail.com [dob]02.11.80 [name]gill silly [email]gill.silly@hotmail.com [dob]03.12.79

我有一个文本文件,里面有一些名字、电子邮件和其他东西。我想捕获电子邮件地址

我不知道这是拆分还是正则表达式问题

以下是一些示例行:

[name]bill billy [email]bill.billy@hotmail.com [dob]01.01.81
[name]mark hilly [email]mark.hilly@hotmail.com [dob]02.11.80
[name]gill silly [email]gill.silly@hotmail.com [dob]03.12.79
我希望能够做一个循环,打印所有的电子邮件地址


谢谢。

您可以按空格分割,然后搜索以
[email]
开头的元素:

line = '[name]bill billy [email]bill.billy@hotmail.com [dob]01.01.81'
items = line.split()
for item in items:
    if item.startswith('[email]'):
        print item.replace('[email]', '', 1)
我会使用正则表达式:

import re

data = '''[name]bill billy [email]bill.billy@hotmail.com [dob]01.01.81
[name]mark hilly [email]mark.hilly@hotmail.com [dob]02.11.80
[name]gill silly [email]gill.silly@hotmail.com [dob]03.12.79'''

group_matcher = re.compile(r'\[(.*?)\]([^\[]+)')

for line in data.split('\n'):
    o = dict(group_matcher.findall(line))
    print o['email']
  • \[
    的字面意思是
    [
  • (.*)
    是一个非贪婪的捕获组。它“扩展”以捕获文本
  • \]
    是字面上的
    ]
  • 是捕获组的开始
  • [^\[]
    匹配除
    [
    之外的任何内容
  • +
    重复上一个模式任意次数
  • 关闭捕获组

您可以将子字符串传递给
拆分
,而不仅仅是单个字符,因此:

email = line.partition('[email]')[-1].partition('[')[0].rstrip()
与简单的
split
解决方案相比,这有一个优势,即它可以在值中包含空格的字段上工作,在具有不同顺序的行上工作(即使它们将
[电子邮件]
作为最后一个字段),等等

概括而言:

def get_field(line, field):
    return line.partition('[{}]'.format(field)][-1].partition('[')[0].rstrip()
但是,我认为它仍然比正则表达式解决方案更复杂。此外,它一次只能搜索一个字段,而不是一次搜索所有字段(不会使其更复杂)。要获得两个字段,您将对每行进行两次解析,如下所示:

for line in data.splitlines():
    print '''{} "babysat" Dan O'Brien on {}'''.format(get_field(line, 'name'), 
                                                      get_field(line, 'dob'))

(当然,我可能误解了该字段。)

假设您有一个包含行的文件

import re

f = open("logfile", "r")
data = f.read()

for line in data.split("\n"):
    match=re.search("email\](?P<id>.*)\[dob", line)
    if match:
             # either store or print the emails as you like
             print match.group('id').strip(), "\n"

收到电子邮件是你唯一想做的事情吗,或者你以后可能想对信息做更多的事情吗?如果是后者,我想你肯定想要Blender的答案。任何依靠纯
split
来分割字段的事(就像这里的大多数答案一样)永远不适用于
name
;任何依赖于
split
ting的
]
可能比正则表达式更复杂(尽管我希望被证明是错误的)。我想我以后可能会想用这个名字来让邮件更具体。如果你只是在匹配像这样的固定字符串,那么使用正则表达式并没有什么真正的优势。将它与Blender的答案进行比较,Blender的答案可以得到所有字段的名称和值,而不仅仅是硬编码的字段,而且更加健壮(例如,对列进行重新排序,使
email
位于
dob
之后,而不是之前)。我认为这是一个需要解决的具体问题,而不是一个一般性问题。概括扩展了“范围”,稳健性就是“根据范围进行调整”。如果您只是想解决特定的问题,与固定的文本字符串进行匹配,则regex不会在简单拆分的基础上添加任何内容,它只是使其速度变慢,并且毫无原因地可读性变差。例如,与JaniSOF的解决方案相比。@karthikr:我想您忘记了
'[name'
将是拆分中的第一个值。@abarnert他之前有不同的答案,我的评论是,是否有一些网站可以轻松描述(r'[(.*)([^[]+])的工作原理我想理解它,而不是仅仅抓住它。但这很好!@gjels:据我所知不是。请参阅我的编辑以获得简要解释。@gjels:Python在其文档中有一个,但它可能不是最适合初学者的教程;尝试用谷歌搜索其他教程。还可以获得一个正则表达式资源管理器程序(每个平台都有无数个,再加上一些在线的),这将有助于您进行操作。只要确保您学习的Python语法perl/PCRE足够接近,但grep、emacs等非常不同。我知道这已经晚了,但给出了一个很好的解释,并允许您测试您的正则表达式。
import re

f = open("logfile", "r")
data = f.read()

for line in data.split("\n"):
    match=re.search("email\](?P<id>.*)\[dob", line)
    if match:
             # either store or print the emails as you like
             print match.group('id').strip(), "\n"
bill.billy@hotmail.com  

mark.hilly@hotmail.com  

gill.silly@hotmail.com  

>>>