【问题标题】:Capture repeated groups in python regex在 python 正则表达式中捕获重复的组
【发布时间】:2017-10-06 10:34:52
【问题描述】:

我有一个邮件日志文件,是这样的:

Aug 15 00:01:06 **** sm-mta*** to=<user1@gmail.com>,<user2@yahoo.com>,user3@aol.com, some_more_stuff
Aug 16 13:16:09 **** sendmail*** to=<user4@yahoo.com>, some_more_stuff
Aug 17 11:14:48 **** sm-mta*** to=<user5@gmail.com>,<user6@gmail.com>, some_more_stuff

我想要的是包含“sm-mta”的行中所有邮件主机的列表。在这种情况下,这将是:['gmail.com', 'yahoo.com', 'aol.com', 'gmail.com', gmail.com']

re.findall(r'sm-mta.*to=.+?@(.*?)[&gt;, ]') 将只返回每个匹配行的第一个主机 (['gmail.com','gmail.com'])

re.findall(r'.+?@(.*?)[&gt;, ]') 将返回正确的列表,但我也需要过滤。有什么解决方法吗?

【问题讨论】:

标签: python regex


【解决方案1】:

如果您不能使用 PyPi 正则表达式库,则必须分两步完成:1) 使用 sm-mta 获取行和 2) 获取您需要的值,例如

重新导入

txt="""Aug 15 00:01:06 **** sm-mta*** to=<user1@gmail.com>,<user2@yahoo.com>,user3@aol.com, some_more_stuff
Aug 16 13:16:09 **** sendmail*** to=<user4@yahoo.com>, some_more_stuff
Aug 17 11:14:48 **** sm-mta*** to=<user5@gmail.com>,<user6@gmail.com>, some_more_stuff"""
rx = r'@([^\s>,]+)'
filtered_lines = [x for x in txt.split('\n') if 'sm-mta' in x]
print(re.findall(rx, " ".join(filtered_lines)))

请参阅Python demo online@([^\s&gt;,]+) 模式将匹配 @ 并将捕获并返回除空格之外的任何 1+ 字符,&gt;,

如果你可以使用 PyPi 正则表达式库,你可能会得到你需要的字符串列表

>>> import regex
>>> x="""Aug 15 00:01:06 **** sm-mta*** to=<user1@gmail.com>,<user2@yahoo.com>,user3@aol.com, some_more_stuff
Aug 16 13:16:09 **** sendmail*** to=<user4@yahoo.com>, some_more_stuff
Aug 17 11:14:48 **** sm-mta*** to=<user5@gmail.com>,<user6@gmail.com>, some_more_stuff"""
>>> rx = r'(?:^(?=.*sm-mta)|\G(?!^)).*?@\K[^\s>,]+'
>>> print(regex.findall(rx, x, regex.M))
['gmail.com', 'yahoo.com', 'aol.com,', 'gmail.com', 'gmail.com']

请参阅 the Python online demoregex demo

模式详情

  • (?:^(?=.*sm-mta)|\G(?!^)) - 在除换行符之外的任何 0+ 个字符或上一场比赛结束的地方之后有 sm-mta 子字符串的行
  • .*?@ - 除换行符之外的任何 0+ 字符,尽可能少,直到 @@ 本身
  • \K - 匹配重置运算符,丢弃当前迭代中到目前为止匹配的所有文本
  • [^\s&gt;,]+ - 除空格之外的 1 个或多个字符,,&gt;

【讨论】:

    【解决方案2】:

    试试regex 模块。

    x="""Aug 15 00:01:06 **** sm-mta*** to=<user1@gmail.com>,<user2@yahoo.com>,user3@aol.com, some_more_stuff
    Aug 16 13:16:09 **** sendmail*** to=<user4@yahoo.com>, some_more_stuff
    Aug 17 11:14:48 **** sm-mta*** to=<user5@gmail.com>,<user6@gmail.com>, some_more_stuff"""
    import regex
    print regex.findall(r"sm-mta.*to=\K|\G(?!^).+?@(.*?)[>, ]", x, version=regex.V1)
    

    输出: ['', 'gmail.com', 'yahoo.com', 'aol.com', '', 'gmail.com', 'gmail.com']

    忽略第一个空匹配。

    https://regex101.com/r/7zPc6j/1

    【讨论】:

      猜你喜欢
      • 2022-11-03
      • 2011-09-19
      • 1970-01-01
      • 2017-09-13
      • 2011-03-11
      • 2017-01-07
      • 2019-12-19
      • 1970-01-01
      相关资源
      最近更新 更多