【问题标题】:how to switch from preg_match to preg_replace?如何从 preg_match 切换到 preg_replace?
【发布时间】:2015-07-06 16:16:09
【问题描述】:

请看下面的代码:

来自:http://www.damnsemicolon.com/php/php-parse-email-body-email-piping

//get rid of any quoted text in the email body
$body_array = explode("\n",$body);
$message = "";
foreach($body_array as $key => $value){

    //remove hotmail sig
    if($value == "_________________________________________________________________"){
        break;

    //original message quote
    } elseif(preg_match("/^-*(.*)Original Message(.*)-*/i",$value,$matches)){
        break;

    //check for date wrote string
    } elseif(preg_match("/^On(.*)wrote:(.*)/i",$value,$matches)) {
        break;

    //check for From Name email section
    } elseif(preg_match("/^On(.*)$fromName(.*)/i",$value,$matches)) {
        break;

    //check for To Name email section
    } elseif(preg_match("/^On(.*)$toName(.*)/i",$value,$matches)) {
        break;

    //check for To Email email section
    } elseif(preg_match("/^(.*)$toEmail(.*)wrote:(.*)/i",$value,$matches)) {
        break;

    //check for From Email email section
    } elseif(preg_match("/^(.*)$fromEmail(.*)wrote:(.*)/i",$value,$matches)) {
        break;

    //check for quoted ">" section
    } elseif(preg_match("/^>(.*)/i",$value,$matches)){
        break;

    //check for date wrote string with dashes
    } elseif(preg_match("/^---(.*)On(.*)wrote:(.*)/i",$value,$matches)){
        break;

    //add line to body
    } else {
        $message .= "$value\n";
    }

}

//compare before and after
echo "$body<br><br><br>$message";

$body 包含完整的电子邮件正文,如果这是回复,则包括引用区域,此循环删除引用区域以获取新的回复作为 $message。但正如那里所建议的那样,循环速度很慢,最好使用 preg_replace 代替。那我该怎么办?

用什么替换模式?我也应该删除 foreach 循环吗?我在下面创建了没有 foreach 循环但似乎错了?请指教。

$patterns = array(
"_________________________________________________________________",
"/^-*(.*)Original Message(.*)-*/i",
"/^On(.*)wrote:(.*)/i",
"/^On(.*)$fromName(.*)/i",
"/^On(.*)$toName(.*)/i",
"/^(.*)$toEmail(.*)wrote:(.*)/i",
"/^(.*)$fromEmail(.*)wrote:(.*)/i",
"/^>(.*)/i",
"/^---(.*)On(.*)wrote:(.*)/i");

$message = preg_replace($patterns, '', $body);

【问题讨论】:

  • 您至少需要 /m 多行修饰符才能使它们在逐行 foreach 之外工作。否则用具体示例和错误消息解释它是如何不起作用的。
  • 能否请您用 preg_replace 而不是 preg_match 重写该链接上的代码块,这样我可以更好地理解它?
  • 下次把代码加到你的问题中,不要链接。
  • 嗯,这么有用的答案我总是在 stackoverflow 上得到!
  • 是否有人在 stackoverflow 上提供有用的建议,而不是上面无意义/无用的垃圾邮件/cmets?

标签: php regex preg-replace preg-match pcre


【解决方案1】:

您已经将范围缩小到一个可行的解决方案。只有几件事需要解决:

  1. 正如@mario 评论的那样,您需要为^s 设置/m 修饰符以匹配每行的开头。
  2. 您的第一个模式需要用分隔符括起来,并锚定到 ^ 和行尾,以保持与原始代码中相同的含义。
  3. 包含换行符以删除整行。
  4. 确保设置了变量$fromName$fromEmail等。
  5. 找到匹配项后,使用(?s:.*) 匹配从那里到正文末尾的所有内容。

代码:

$patterns = array(
    "/^_{30,}$(?s:.*)/m",
    "/^.*Original Message(?s:.*)/im",
    "/^(?:---.*)?On .* wrote:(?s:.*)/im",
    "/^On .* $fromName(?s:.*)/im",
    "/^On .* $toName(?s:.*)/im",
    "/^.*$toEmail(.*)wrote:(?s:.*)/im",
    "/^.*$fromEmail.* wrote:(?s:.*)/im",
    "/^>.*/ims",
);
$message = preg_replace($patterns, '', $body);
echo "$body<br><br><br>$message";

Run this code here


忠告:

考虑到它也会像这样剥离行:

only thing I wrote: ...

【讨论】:

  • 谢谢,那我应该怎么做才能防止你提到的问题呢?如何让它只删除电子邮件的引用区域?
  • 邮件回复正文中不一定会出现fromName和fromEmail,那么如何防止你在#4中提到的问题呢?
  • 这里总会有例外,因为没有完美的解决方案。使用不同的电子邮件进行测试,如果可以,请删除/i,并继续在线搜索以获取更多信息。这是一篇您可能会感兴趣的文章:Parse email content from quoted reply
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-23
  • 2012-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-11
相关资源
最近更新 更多