【问题标题】:SpamAssassin Regular Expression not matchingSpamAssassin 正则表达式不匹配
【发布时间】:2015-07-07 22:29:00
【问题描述】:

我在这里阅读过类似的问题,但由于并非所有正则表达式都是平等的,因此我无法找到解决问题的方法。

我正在为 SpamAssassin 制定一项规则,该规则将判断收件人的电子邮件用户名是否包含在邮件正文中。例如,发送到testuser@somedomain.com 的电子邮件在邮件正文中包含testuser。我已经在 Regex-101 上编写并测试了一个正则表达式,并且能够按预期匹配它,但是当我创建规则时,它在 SpamAssassin 中测试时不起作用。

这是表达式:

/To:\s([a-z0-9][-a-z0-9]{1,19})\@somedomain\.com[a-z0-9\s=;:\/\.-]*\1\b/i

应该做的是匹配To: 标头中的电子邮件地址(或匹配格式To: user@somedomain.com 的邮件正文中的任何位置。正如我之前提到的,表达式在 Regex-101 上按预期匹配,但是当我在 SpamAssassin 中制定规则时,它不匹配。

如果我删除前导To:\s,那么它确实匹配,但我只关心匹配To: 标头中的电子邮件。我已经尝试过表达的这些不同的突变:

/To:\s([a-z0-9][-a-z0-9]{1,19})\@somedomain\.com[a-z0-9\s=;:\/\.-]*\1\b/i
/To: ([a-z0-9][-a-z0-9]{1,19})\@somedomain\.com[a-z0-9\s=;:\/\.-]*\1\b/i
/To:[\s]{0,2}([a-z0-9][-a-z0-9]{1,19})\@somedomain\.com[a-z0-9\s=;:\/\.-]*\1\b/i
/:\s([a-z0-9][-a-z0-9]{1,19})\@somedomain\.com[a-z0-9\s=;:\/\.-]*\1\b/i

/\s([a-z0-9][-a-z0-9]{1,19})\@somedomain\.com[a-z0-9\s=;:\/\.-]*\1\b/i

前面的规则都不匹配,但这条匹配:

/([a-z0-9][-a-z0-9]{1,19})\@somedomain\.com[a-z0-9\s=;:\/\.-]*\1\b/i

这是我用于测试的文本:

Subject: Test spam mail (GTUBE) private jet rental
Message-ID: <GTUBE1.1010101@example.net>
Date: Wed, 23 Jul 2003 23:30:00 +0200
From: Sender <sender@live.com>
To: recipient@somedomain.com
Precedence: junk
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
recipient
This is the GTUBE, the
    Generic
    Test for
    Unsolicited
    Bulk
    Email

哪个应该匹配To: recipient@somedomain.com ....recipient,但只有当我从表达式中删除To:\s 时才能使其匹配。完整的表达式在 Regex-101 中测试,所以它似乎是 SpamAssassin 特有的,但我不确定。

编辑

这是表达式的更新版本,不允许在用户名末尾使用破折号,但允许在中间:

/\bTo:\s([a-z0-9][-a-z0-9]{0,18}[a-z0-9])\@somedomain\.com[a-z0-9\s=;:\/\.-]*\b\1\b/i

【问题讨论】:

  • 你为什么要在末尾添加用户名的反向引用(后跟单词边界)?有一件事,您允许在 backref 末尾使用破折号 - 字符,但破折号 不是 一个单词,因此边界必须在实际单词之前。跨度>
  • 用户名的反向引用位于末尾,后跟单词边界,因此,如本例所示,recipient 需要出现在 recipient@somedomain.com 之后的文本中,以便匹配的规则。单词边界是这样的,如果用户名是另一个单词的一部分,则不匹配,例如recipients
  • - 允许在 backref 中处理电子邮件地址,例如some-user55@somedomain.com
  • 那么你不应该让破折号-作为用户名的最后一个字符,这会导致问题。如果您的引擎支持条件,您可以使用条件边界 (?(?&lt;=\w)\b) 来克服它。
  • 无论如何,只要从头到尾剥离表达式,直到找到一些匹配项。根据需要修改,然后添加回来。

标签: regex email spamassassin


【解决方案1】:

在聊天中 @sln 的帮助下,我们想出了以下符合预期的完整规则的表达式:

/To:\s+([a-z0-9][-a-z0-9]{1,18}[a-z0-9])\@somedomain\.com[\S\s]*?\1\b/i

这将匹配To: username@somedomain.com ... username,因此它应该在大多数情况下匹配在邮件正文中包含收件人用户名的任何电子邮件。在我们的案例中,我们收到的许多垃圾邮件都会包含用户名,例如:

Greetings username!  Blah Blah Blah spam message.

最终修复它的方法是将电子邮件地址后面的 [a-z0-9\s=;:\/\.-]* 替换为 [\S\s]*?

【讨论】:

    猜你喜欢
    • 2021-04-07
    • 1970-01-01
    • 2021-10-29
    • 1970-01-01
    相关资源
    最近更新 更多