代码之家  ›  专栏  ›  技术社区  ›  Richard Simões

Perl和Python之间的regex行为有什么不同?

  •  3
  • Richard Simões  · 技术社区  · 16 年前

    我有几个电子邮件地址, 'support@company.com' '1234567@tickets.company.com' .

    在Perl中,我可以 To: 一行原始电子邮件,查找上述地址

    /\w+@(tickets\.)?company\.com/i
    

    在python中,我简单地将上面的regex编写为 '\w+@(tickets\.)?company\.com' 要求相同的结果。然而, support@company.com 完全找不到,第二个findall返回一个仅包含 'tickets.' . 如此清晰 '(tickets\.)?' 是问题所在,但是Perl和Python之间的正则表达式规则到底有什么不同呢?

    4 回复  |  直到 16 年前
        1
  •  7
  •   ephemient    16 年前

    文件 re.findall :

    findall(pattern, string, flags=0)
        Return a list of all non-overlapping matches in the string.
    
        If one or more groups are present in the pattern, return a
        list of groups; this will be a list of tuples if the pattern
        has more than one group.
    
        Empty matches are included in the result.
    

    自从 (tickets\.) 是一组, findall 返回而不是整个匹配项。如果需要整个匹配,请在整个模式周围放置一个组和/或使用非分组匹配,即。

    r'(\w+@(tickets\.)?company\.com)'
    r'\w+@(?:tickets\.)?company\.com'
    

    请注意,您必须挑选出由返回的每个元组的第一个元素。 芬德尔 在第一种情况下。

        2
  •  4
  •   chaos    16 年前

    我认为问题在于你对提取价值的期望。尝试在当前的python代码中使用此代码:

    '(\w+@(?:tickets\.)?company\.com)'
    
        3
  •  2
  •   David Berger    16 年前

    我有两个问题:

    1. 您需要使用原始字符串以避免必须转义“ \
    2. 你需要逃跑” .

    所以尝试:

    r'\w+@(tickets\.)?company\.com'
    

    编辑

    样品输出:

    >>> import re
    >>> exp = re.compile(r'\w+@(tickets\.)?company\.com')
    >>> bool(exp.match("s@company.com"))
    True
    >>> bool(exp.match("1234567@tickets.company.com"))
    True
    
        4
  •  1
  •   Chas. Owens    16 年前

    正则表达式没有区别,但在您所要查找的内容上有区别。你的正则表达式只捕获 "tickets." 如果它存在于两个正则表达式中。你可能想要这样的东西

    #!/usr/bin/python
    
    import re
    
    regex = re.compile("(\w+@(?:tickets\.)?company\.com)");
    
    a = [
        "foo@company.com", 
        "foo@tickets.company.com", 
        "foo@ticketsacompany.com",
        "foo@compant.org"
    ];
    
    for string in a:
        print regex.findall(string)