0

我在找出识别电子邮件正文中内联回复/转发开头的模式时遇到了一些麻烦,有一些更简单的方法只是以“开始转发消息”之类的开头,但回复有点复杂:

On 12-06-13 10:56 AM, "John Doe" <john.doe@some.tld> wrote:

显然,常量将是“On”和“wrote:”。我希望能够仅找到第一个匹配项,然后将其后的所有内容包装在一个 div 中,并使用 display:none 或什至只是使用 substr($body,0, POSITION_OF_MATCH) 消除它。

我遇到的一个问题是它没有捕捉到第一次发生,第二个是我无法让贪婪正常工作。

到目前为止,我的进展(已经回落到至少部分工作的版本)是:

preg_match("/On [^>]* wrote:/i",$content,$matches,PREG_OFFSET_CAPTURE);

任何帮助将不胜感激!

4

4 回答 4

1

我想知道您当前的版本是如何工作的,因为您不可能匹配关闭的>. 但你可以这样做:

$content = preg_replace('/(On [^>]*> wrote:).*$/s', '$1', $content);

它将匹配第一个On ... wrote:和之后的所有内容,直到字符串的末尾。并将其替换为On ... wrote:.

于 2012-11-06T18:32:35.477 回答
1

您可能可以按元素对其进行分解;所以你基本上有:

On DATE, "NAME" <EMAIL> wrote:

然后,您可以表征DATENAMEEMAIL

  • DATE由数字、破折号、空格、冒号和字母组成。但是,它以逗号结尾,因此您可以改用它。
  • NAME由字母和空格组成,尽管它由引号分隔,您可能可以处理。
  • EMAIL有点复杂,但电子邮件不能包含字符>,因此您应该能够捕获除此之外的所有内容。

所以你基本上得到:

On [anything but comma], "[anything but "]" <[anything but >]> wrote:

在正则表达式中,它类似于:

/^On ([^,]+), \"([^\"]+)\" <([^>]+)> wrote:$/

然后,在使用时preg_match,您可以从某个$matches数组(索引 1 到 3)中获取匹配项。

于 2012-11-06T18:33:28.003 回答
1

我建议

$email = preg_match('/^On [^"]*"[^"]*" <([^>]*)> wrote:$/', $str, $re) ? $re[1] : '';

请参阅此演示

于 2012-11-06T19:32:07.010 回答
1

我很欣赏其他答案,但他们都没有真正考虑到我正在处理的回复字符串中的许多可能变化,这可能是我没有正确解释或提供更多选项的错。不过,我已经为每个人的努力 +1 了。

经过一天的打开和关闭后,似乎效果最好的最终解决方案是:

/On (Mon|Tue|Wed|Thu|Fri|Sat|Sun|[[:digit:]]{1,2})(.*?) wrote:/i

它开头的选项列表涵盖了一系列不同的回复类型,以“周二…”或“23 日…”或“1 日…”等开头,确保我抱怨的贪婪about 并没有从其他地方的随机 "on" 字符串中吸收太多, (.*?) 负责处理名称/电子邮件部分的其余部分,最后用 "wrote:" 完成它。

于 2012-11-07T14:41:31.837 回答