【发布时间】:2011-09-21 16:05:38
【问题描述】:
给定一个代表电子邮件整个文本正文的字符串,我想只提取发件人撰写的部分如果它只是一个连续的文本块。例如:
Dear Sir:
That is a good point.
On Wednesday, June 1, John wrote:
> Hello world.
将提取:
Dear Sir:
That is a good point.
通过连续,我的意思是块可能包含单个换行符,但不是连续的换行符。所以这不匹配:
Dear Sir:
That is a good point.
On Wednesday, June 1, John wrote:
> Hello world.
“发件人撰写的部分”是指电子邮件正文可能包含回复或转发的文本或签名,我想排除所有这些内容(我们称其为“非原创内容”)。虽然野外可能有很多变化,但(目前)仅处理以下情况就足够了:
1) 以两个破折号开头的行(例如:----- 转发的消息 -----),因为签名通常在一行的开头也有两个破折号
2) 以“On”开头的行后跟以“>”开头的行来捕获这种格式:
On Wednesday, June 1, John wrote:
> Hello world.
如果非原始块上方没有任何内容(没有非空白),则不应该有匹配。
最后,请记住,在消息的开头以及目标文本块和消息结尾之间或目标文本块和非目标文本块的开头之间可能有任意数量的空白。原创内容。另外,请记住,电子邮件中的回车可能只是换行符或 crlf。
这是我的第一次尝试,比我开始写这篇文章时的想法更接近;它使用 s 标志:
^\s*(\S[^(?:\n\n|\r\n\r\n)]*\S)\s*(?:$|(?:$|\-\-.*|On [^\n]*\n\>.*))
从我目前的测试来看,如果目标文本只有一行,它似乎可以工作,但如果它超过一行则不行。所以主要缺陷似乎在这部分:
_______[^(?:\n\n|\r\n\r\n)]*________________________________________
更新:这是我正在使用的解决方案:
'/\A\s*((?:[^\r\n]+\r?(?:\n|\z))+)\s*(?:\z|(--.*|On .+:\n\>.*))/s'
请注意,“On”行可能会换成多行(例如,如果日期和电子邮件地址很长),但通常会有一个“:\n>”。
【问题讨论】:
-
嗯...我的代码块中的蓝色不是故意的。
-
@dlo lang-none
标签: regex