【问题标题】:Repeated regex/PCRE named capturing groups with a match in front重复正则表达式/PCRE 命名捕获组,前面有匹配项
【发布时间】:2019-07-16 13:47:10
【问题描述】:

我正在尝试解析 sendmail 日志。这些是分开的 - 'to' 和 'from' 在不同的行。我想匹配 'to' 以确定我们正在查看的行是 'to' 行,然后捕获尽可能多的电子邮件地址。有许多与此类似的帮助请求,但没有一个(我已经找到并且我保证我一直在寻找!)完全符合相同的情况。

我曾尝试在 Stack Overflow 上使用多种解决方案,但均未成功。问题是'to='不是可选的,它是一个要求。这可能是 PCRE 正则表达式吗?

到目前为止的正则表达式(仅匹配第一个电子邮件地址):

to\=((\<)?(?P<to>.+?\@.+?)(\>)?\,)

示例行:

Jul 16 13:35:05 mailserver sendmail[30892]: xxxxxxxxxxxxxx: to=user1@example.derp,user2@example.derp,user3@example.derp, delay=00:00:00, xdelay=00:00:00, mailer=smtp, pri=91785, relay=relay.example.derp [1.2.3.4], dsn=2.0.0, stat=Sent (<xxxxxxxxxxxxx.xxxxxxxxxxxx@mailserver.derp> Queued mail for delivery)

理想情况下,“to\=”之后的匹配将匹配现有的电子邮件地址,而不仅仅是第一个。如果有一个答案可以解决我错过/无法适应我的场景的问题 - 道歉。

【问题讨论】:

    标签: regex pcre regex-group


    【解决方案1】:

    您可以使用\G 锚点来获取迭代匹配,断言上一次匹配结束时的位置,并在捕获组中捕获电子邮件地址。

    (?:to=|\G(?!^))([^,\s@]+@[^@,\s]+),
    

    说明

    • (?:非捕获组
      • to= 匹配字面意思
      • |或者
      • \G(?!^) 在上一场比赛结束时断言位置,而不是在开始时
    • )关闭非捕获组
    • (捕获组1
      • [^,\s@]+@[^@,\s]+ 否定字符类,匹配除逗号、@ 或空格以外的任何字符,并匹配 @ 之间
    • ),关闭第1组并匹配逗号

    Regex demo

    【讨论】:

    • 非常感谢您的帮助。由于正在训练,我现在无法测试!
    • 有些行似乎有 包裹在电子邮件地址周围,即 ,这破坏了上述内容。这是一个可以接受的修复: (?:to=|\G(?!^))()(?P[^,\s@]+@[^@,\s]+?) (>)?,
    • 这看起来不错: ,\s*delay=.+|(?[^@,=]+@[ ^\,]+)
    • 您可以这样做,也可以省略捕获组,因此只需使用&lt;?&gt;?。请注意,如果只有 存在,它也会匹配电子邮件,因为两者都是可选的。
    【解决方案2】:

    这是我最终使用的:

    ,\s*delay=.+|(?<=to=|,),?(<)?(?<to>[^@,=]+@[^<>\,]+) 
    

    它并不完美,但它对我有用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-10-28
      • 2014-11-13
      • 2021-07-29
      • 2021-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多