从邮件主题中去除 "FWD"、"RE" 等的正则表达式/代码

14 投票
3 回答
7667 浏览
提问于 2025-04-17 12:23

我想要处理一下电子邮件的主题行,把里面的“Re:”、“Fwd”和其他一些杂七杂八的东西去掉。比如说,“[Fwd] Re: Jack and Jill's Wedding”应该变成“Jack and Jill's Wedding”。

应该有人做过类似的事情,所以我希望你能给我推荐一些经过验证的正则表达式或者代码。

这里有一些需要清理的例子,来自这个页面。那个页面上的正则表达式效果还不错,但还不是完全符合我的需求。

Fwd : Re : Re: Many
Re : Re: Many
Re  : : Re: Many
Re:: Many
Re; Many
: noah - should not match anything
RE--
RE: : Presidential Ballots for Florida
[RE: (no subject)]
Request - should not match anything
this is the subject (fwd)
Re: [Fwd: ] Blonde Joke
Re: [Fwd: [Fwd: FW: Policy]]
Re: Fwd: [Fwd: FW: "Drink Plenty of Water"]
FW: FW: (fwd) FW:  Warning from XYZ...
FW: (Fwd) (Fwd) 
Fwd: [Fwd: [Fwd: Big, Bad Surf Moving]]
FW: [Fwd: Fw: drawing by a school age child in PA (fwd)]
Re: Fwd

3 个回答

2

下面这个正则表达式可以匹配我预期的所有情况。我不确定你是否会同意,因为并不是每种情况都有明确的说明。虽然可能有更简单的方法,但这个方法是可以用的:

/^((\[(re|fw(d)?)\s*\]|[\[]?(re|fw(d)?))\s*[\:\;]\s*([\]]\s?)*|\(fw(d)?\)\s*)*([^\[\]]*)[\]]*/i

最后匹配的结果将是去掉多余部分的内容。

13

根据不同国家和语言,邮件主题前缀有几种变化:维基百科:邮件主题缩写列表

在巴西:RES 和 RE 是一样的, 在德国:AW 和 RE 也是一样的

下面是一个 Python 的例子:

#!/usr/local/bin/python
# -*- coding: utf-8 -*-
import re
p = re.compile( '([\[\(] *)?(RE?S?|FYI|RIF|I|FS|VB|RV|ENC|ODP|PD|YNT|ILT|SV|VS|VL|AW|WG|ΑΠ|ΣΧΕΤ|ΠΡΘ|תגובה|הועבר|主题|转发|FWD?) *([-:;)\]][ :;\])-]*|$)|\]+ *$', re.IGNORECASE)
print p.sub( '', 'RE: Tagon8 Inc.').strip()

下面是一个 PHP 的例子:

$subject = "主题: Tagon8 - test php";
$subject = preg_replace("/([\[\(] *)?(RE?S?|FYI|RIF|I|FS|VB|RV|ENC|ODP|PD|YNT|ILT|SV|VS|VL|AW|WG|ΑΠ|ΣΧΕΤ|ΠΡΘ|תגובה|הועבר|主题|转发|FWD?) *([-:;)\]][ :;\])-]*|$)|\]+ *$/im", '', $subject);
var_dump(trim($subject));

终端命令:

$ python test.py
Tagon8 Inc.
$ php test.php
string(17) "Tagon8 - test php"

注意:这是来自 mathematical.coffee 的正则表达式。 还添加了其他语言的前缀: 中文、丹麦语、挪威语、芬兰语、法语、德语、希腊语、希伯来语、意大利语、冰岛语、瑞典语、葡萄牙语、波兰语、土耳其语

我使用了“strip/trim”来去掉空格

19

试试这个(替换成''):

/([\[\(] *)?(RE|FWD?) *([-:;)\]][ :;\])-]*|$)|\]+ *$/igm

(如果你把每个主题作为自己的字符串传入,那么就不需要 m 修饰符了;这个修饰符的作用是让 $ 匹配行的结束,而不仅仅是字符串的结束,适用于多行字符串输入)。

你可以在 这里 查看效果。

正则表达式的解释:

([\[\(] *)?            # starting [ or (, followed by optional spaces
(RE|FWD?) *            # RE or FW or FWD, followed by optional spaces
([-:;)\]][ :;\])-]*|$) # only count it as a Re or FWD if it is followed by 
                       # : or - or ; or ] or ) or end of line
                       # (and after that you can have more of these symbols with
                       #  spaces in between)
|                      # OR
\]+ *$                 # match any trailing \] at end of line 
                       # (we assume the brackets () occur around a whole Re/Fwd
                       #  but the square brackets [] occur around the whole 
                       #  subject line)

标志。

i:不区分大小写。

g:全局匹配(匹配所有你能找到的 Re/Fwd)。

m:让正则表达式中的 '$' 匹配多行输入的行结束,而不仅仅是字符串的结束(如果你一次性把所有输入主题都传给正则表达式,这个修饰符才有用。如果你每次只传一个主题,那么可以去掉它,因为行结束 就是 字符串的结束)。

撰写回答