Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 忽略与正则表达式不完全匹配的字符串?_Python_Regex - Fatal编程技术网

Python 忽略与正则表达式不完全匹配的字符串?

Python 忽略与正则表达式不完全匹配的字符串?,python,regex,Python,Regex,我想使用正则表达式返回电子邮件的所有收件人。例如: Date: Wed, 6 Dec 2000 02:03:00 -0800 (PST) From: donald.herrick@enron.com To: brianherrick@email.msn.com, herriceu2@tdprs.state.tx.us, robertherrick@bankunited.com, kristi.demaiolo@enron.com, suresh.raghavan@enron.

我想使用正则表达式返回电子邮件的所有收件人。例如:

Date: Wed, 6 Dec 2000 02:03:00 -0800 (PST)
From: donald.herrick@enron.com
To: brianherrick@email.msn.com, herriceu2@tdprs.state.tx.us, 
    robertherrick@bankunited.com, kristi.demaiolo@enron.com, 
    suresh.raghavan@enron.com, harry.arora@enron.com
Subject: FW: If Santa Answered his mail...
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
X-From: Donald W Herrick
X-To: brianherrick@email.msn.com, HERRICEU2@tdprs.state.tx.us, RobertHerrick@bankunited.com, Kristi Demaiolo, Suresh Raghavan, Harry Arora
X-cc: 
X-bcc: 
应返回(从“到:”行)brianherrick@email.msn.com, herriceu2@tdprs.state.tx.us, robertherrick@bankunited.com,克里斯蒂。demaiolo@enron.com,苏雷什。raghavan@enron.com骚扰arora@enron.com

但是不是(从“X-To:”行)brianherrick@email.msn.com, HERRICEU2@tdprs.state.tx.us, RobertHerrick@bankunited.com

我当前的正则表达式是
re.findall([To:\s][\w\.-]+@[\w\.-]+,text)
,它返回从“To:”、“X-To:”和“from:”行的所有内容

我的问题:

  • 为什么“发件人:”行上的电子邮件地址也会被返回?信息技术 与正则表达式的
    [To:\s]
    部分不匹配
  • 我如何确保只有“收件人:”后面的电子邮件地址是 返回?(即,如何排除以下电子邮件地址 “X-To:”?我认为您可以为此使用前瞻断言,但我不确定如何做到这一点

  • 您误解了字符类的作用;您的模式匹配字符串中包含
    T
    o
    或空白字符的任何位置

    这是因为
    [To:\s]
    为字符类建模,集合中的任何一个字符都将匹配。这就是为什么
    From:
    行匹配;
    d
    之间的空格在这里就足够了

    如果需要验证整个标题名,请使用
    ^
    将匹配锚定到行的开头,但删除该字符类:

    r'^To:\s+[\w\.-]+@[\w\.-]+'
    
    现在,如果使用
    re.MULTILINE
    标志,则
    To:
    部分仅在行首匹配:

    >>> import re
    >>> text = '''\
    ... Date: Wed, 6 Dec 2000 02:03:00 -0800 (PST)
    ... From: donald.herrick@enron.com
    ... To: brianherrick@email.msn.com, herriceu2@tdprs.state.tx.us, 
    ...     robertherrick@bankunited.com, kristi.demaiolo@enron.com, 
    ...     suresh.raghavan@enron.com, harry.arora@enron.com
    ... Subject: FW: If Santa Answered his mail...
    ... Mime-Version: 1.0
    ... Content-Type: text/plain; charset=us-ascii
    ... Content-Transfer-Encoding: 7bit
    ... X-From: Donald W Herrick
    ... X-To: brianherrick@email.msn.com, HERRICEU2@tdprs.state.tx.us, RobertHerrick@bankunited.com, Kristi Demaiolo, Suresh Raghavan, Harry Arora
    ... X-cc: 
    ... X-bcc: 
    ... '''
    >>> re.findall(r'^To:\s+[\w\.-]+@[\w\.-]+', text)
    []
    >>> re.findall(r'^To:\s+[\w\.-]+@[\w\.-]+', text, flags=re.M)
    ['To: brianherrick@email.msn.com']
    
    这只能与第一个电子邮件地址匹配,并且只有当它不包含全名之类的内容时(例如,
    Brian Herrick

    您必须匹配整个标题:

    这会将
    匹配到:
    标题,后跟任意数量的标题续行(以空格开头):

    你必须从中提取电子邮件地址

    就我个人而言,我会研究的,相反,这将使它更容易抓取标题:

    import email
    
    message = email.message_from_string(text)
    to_headers = message.get_all('to')
    addresses = email.utils.getaddresses(to_headers)
    
    演示:

    现在你有了所有的电子邮件地址

    在使用正则表达式时也可以应用:

    >>> email.utils.getaddresses(re.findall(r'^To:\s+((?:.*(?:\n[ \t]+)?)*)', text, flags=re.M))
    [('', 'brianherrick@email.msn.com'), ('', 'herriceu2@tdprs.state.tx.us'), ('', 'robertherrick@bankunited.com'), ('', 'kristi.demaiolo@enron.com'), ('', 'suresh.raghavan@enron.com'), ('', 'harry.arora@enron.com')]
    

    作为@MartijnPieters答案的补充,regex可能不是合适的工具


    regex
    模块:无限查找和其他功能

    如果您想使用正则表达式,我建议您使用未完成而不是
    re
    。此正则表达式将返回所有匹配项:

    (?<=(?<!X\S+)To:\s*(?:[^@\s]+@[^\,\s]+,\s*)*?)[^@\s]+@[^\,\s]+
    
    解释

    • 我们有一个大的查找,然后是一个非常基本的电子邮件匹配器:
      [^@\s]+@[^\,\s]+
      ,它匹配任何不是arrobas或空格字符的字符,然后是arrobas,然后是任何不是逗号或空格字符的字符(输入中电子邮件分隔符的结尾)
    • 如果需要,可以用更复杂的电子邮件正则表达式替换电子邮件匹配器
    • 现在转到大的lookback```(?to:,只要它前面没有前面有
      Xsomething
      ,正如负lookback
    • 非捕获组
      (?:[^@\s]+[^\,\s]+,\s*)*?
      根据需要匹配表达式
      [^@\s]+[^\,\s]+,\s*
      中的
      *?
      量词),以允许后面的内容匹配。这是一个“电子邮件跳过器”,允许我们在每次匹配后逐渐跳过越来越多的电子邮件
    • [^@\s]+@[^\,\s]+,\s*
      只是一封简陋的电子邮件,后跟一个coma和可选的空白字符(
      \s
      不仅匹配空格,还匹配回车符、制表符等)

    [To:\s]
    不会做你认为它会做的事。
    'o:TT TTTo oT::'
    也匹配,因为
    […]
    为一组字符建模,而不是序列。如果在字符集后有一个
    *
    +
    ,否则它只匹配一个字符。换句话说,当前表达式匹配
    T.-----。whoopee@foobar
    仅仅因为它以
    T
    o
    或空格中的一个开头。Thanx。我会的查看电子邮件包,但我不知道这是否是我正在寻找的,因为我正在为txt文件(本例中碰巧包含电子邮件)构建一个通用解析器。我在表达式中有
    [to:\s]
    的原因是,当我有
    to:\s
    和多行标志时,它只返回第一个电子邮件地址(brianherrick@email.msn.com),其中,我需要将所有匹配项返回到
    [\w\.-]+@[\w\.-]+
    ,这些匹配项出现在“to:”之后,但不在“X-to:”之后。这可能吗?@user3797035:您只能匹配整个标题,而不能匹配单个电子邮件地址。@user3797035:添加了有关如何使用正则表达式提取所有
    收件人:
    标题的详细信息,以及如何使用
    电子邮件.utils
    包将这些标题解析为电子邮件地址的详细信息。您好,谢谢您的建议。您愿意成为能够解释正则表达式字符串的作用吗?特别是关于前向和后向断言?此表达式是否与
    re
    不兼容?不,它不能与
    re
    一起工作。支持此功能的仅有两个引擎是.NET和
    regex
    模块(四大引擎中的两个,分别是PCRE和Perl)。对于Python中任何严重的正则表达式,您都需要该模块,该模块旨在替换
    re
    。将添加解释。:)好的,添加了一个很长的解释,但如果有不清楚的地方或您需要更多详细信息,请告诉我。:)如果你有,比如说,一个
    X-Original-To:
    标题,这将不起作用。你最好锚定到一行的开头;电子邮件标题确实跟随RFC是有原因的。:-@MartijnPieters谢谢你的想法,编辑了lookback来解释它。:)我没有考虑
    >>> import email
    >>> m = email.message_from_string(text)
    >>> m.get_all('to')
    ['brianherrick@email.msn.com, herriceu2@tdprs.state.tx.us, \n    robertherrick@bankunited.com, kristi.demaiolo@enron.com, \n    suresh.raghavan@enron.com, harry.arora@enron.com']
    >>> email.utils.getaddresses(m.get_all('to'))
    [('', 'brianherrick@email.msn.com'), ('', 'herriceu2@tdprs.state.tx.us'), ('', 'robertherrick@bankunited.com'), ('', 'kristi.demaiolo@enron.com'), ('', 'suresh.raghavan@enron.com'), ('', 'harry.arora@enron.com')]
    
    >>> email.utils.getaddresses(re.findall(r'^To:\s+((?:.*(?:\n[ \t]+)?)*)', text, flags=re.M))
    [('', 'brianherrick@email.msn.com'), ('', 'herriceu2@tdprs.state.tx.us'), ('', 'robertherrick@bankunited.com'), ('', 'kristi.demaiolo@enron.com'), ('', 'suresh.raghavan@enron.com'), ('', 'harry.arora@enron.com')]
    
    >>> from email.parser import Parser
    >>> headers = Parser().parsestr(email_str)
    >>> pprint.pprint(map(str.strip, headers['to'].split()))
    ['brianherrick@email.msn.com,',
     'herriceu2@tdprs.state.tx.us,',
     'robertherrick@bankunited.com,',
     'kristi.demaiolo@enron.com,',
     'suresh.raghavan@enron.com,',
     'harry.arora@enron.com']
    
    (?<=(?<!X\S+)To:\s*(?:[^@\s]+@[^\,\s]+,\s*)*?)[^@\s]+@[^\,\s]+
    
    import regex
    subject = """Date: Wed, 6 Dec 2000 02:03:00 -0800 (PST)
    From: donald.herrick@enron.com
    To: brianherrick@email.msn.com, herriceu2@tdprs.state.tx.us, 
        robertherrick@bankunited.com, kristi.demaiolo@enron.com, 
        suresh.raghavan@enron.com, harry.arora@enron.com
    Subject: FW: If Santa Answered his mail...
    Mime-Version: 1.0
    Content-Type: text/plain; charset=us-ascii
    Content-Transfer-Encoding: 7bit
    X-From: Donald W Herrick
    X-To: brianherrick@email.msn.com, HERRICEU2@tdprs.state.tx.us, RobertHerrick@bankunited.com, Kristi Demaiolo, Suresh Raghavan, Harry Arora
    X-cc: 
    X-bcc: """
    pattern = "(?<=(?<!X\S+)To:\s*(?:[^@\s]+@[^\,\s]+,\s*)*?)[^@\s]+@[^\,\s]+"
    
    for match in regex.finditer(pattern, subject):
        print(match.group())
    
    brianherrick@email.msn.com
    herriceu2@tdprs.state.tx.us
    robertherrick@bankunited.com
    kristi.demaiolo@enron.com
    suresh.raghavan@enron.com
    harry.arora@enron.com