【问题标题】:PHP - Gmail-like Email Content SeparationPHP - 类似 Gmail 的电子邮件内容分离
【发布时间】:2011-06-18 06:59:19
【问题描述】:

我正在构建一个票务系统,但我不想放其中一条消息

************************* REPLY ABOVE THIS LINE ***********************

Gmail 倾向于用他们的“引用文本”来做一个很好的主意。有谁知道任何预制脚本或方法可以轻松做到这一点?我正在尝试将他们的回复反馈到我们的系统中。

谢谢, 克里

【问题讨论】:

  • 我猜他们有很多测试数据并开发了一个“秘密”算法。
  • 这可能是“差异”过程的变体——将新消息与旧消息的内容进行比较。我建议沿着这条线进行研究。

标签: php email gmail


【解决方案1】:

我认为你需要像我的完整数组差异函数这样的东西:

 /** 
        Full Array Diff implemented in pure php, written from scratch. 
        Copyright (C) 2011 Andres Morales <yo@kijote.com.ar> 

        This program is free software; you can redistribute it and/or 
        modify it under the terms of the GNU General Public License 
        as published by the Free Software Foundation; either version 2 
        of the License, or (at your option) any later version. 

        This program is distributed in the hope that it will be useful, 
        but WITHOUT ANY WARRANTY; without even the implied warranty of 
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
        GNU General Public License for more details. 

        You should have received a copy of the GNU General Public License 
        along with this program; if not, write to the Free Software 
        Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. 

        http://www.gnu.org/licenses/gpl.html 

        About:
        I needed a function to compare a email and its response but array_diff()
        does not cover my expectations. So I reimplement a full array diff function.
        You can use it directly in your code and adopt to your needs.

        Contact:
        yo@kijote.com.ar <Andres Morales> 
**/ 
function farray_diff($array1, $array2){
        $out = array();
        $max_arr = count($array1) > count($array2)? count($array1) : count($array2);

        $i = 0;
        $j = 0;

        while($i < $max_arr && $j< $max_arr){
            if($array1[$i] == $array2[$j]){
                array_push($out, $array1[$i]);
            }
            else {
                if(in_array($array1[$i], array_slice($array2, $j))){
                    for($k = $j; $k<$max_arr; $k++){
                        if($array1[$i]==$array2[$k]){
                            array_push($out, $array2[$k]);
                            $j = $k;
                            break;
                        }
                        else{
                            array_push($out, array('o' => '', 'n' => $array2[$k]));
                        }
                    }
                }
                elseif(in_array($array2[$j], array_slice($array1, $i))){
                    for($k = $i; $k<$max_arr; $k++){
                        if($array2[$j]==$array1[$k]){
                            array_push($out, $array1[$k]);
                            $i = $k;
                            break;
                        }
                        else {
                            array_push($out, array('o' => $array1[$k], 'n' => ''));
                        }
                    }
                }
                else{
                    if(!empty($array1[$i]))
                        array_push($out, array('o' => $array1[$i], 'n' => $array2[$j]));
                    else
                        array_push($out, array('o' => '', 'n' => $array2[$j]));
                }
            }
            $i++; $j++;
        }
        return $out;
    }

所以,你可以像下面的例子一样简单地使用它:

$str1 = "This is a simple text that can you reply, so can you do it?";
$str2 = "I response in your text: This is a simple text (no so simple) that can be replied, so can you do it? Yes, I can!";
// Printing the full array diff of single space exploded strings
print_r(farray_diff(explode(' ', $str1), explode(' ', $str2)));

返回:

Array
(
    [0] => Array
        (
            [o] => 
            [n] => I
        )

    [1] => Array
        (
            [o] => 
            [n] => response
        )

    [2] => Array
        (
            [o] => 
            [n] => in
        )

    [3] => Array
        (
            [o] => 
            [n] => your
        )

    [4] => Array
        (
            [o] => 
            [n] => text:
        )

    [5] => This
    [6] => is
    [7] => a
    [8] => simple
    [9] => text
    [10] => Array
        (
            [o] => 
            [n] => (no
        )

    [11] => Array
        (
            [o] => 
            [n] => so
        )

    [12] => Array
        (
            [o] => 
            [n] => simple)
        )

    [13] => that
    [14] => can
    [15] => Array
        (
            [o] => 
            [n] => be
        )

    [16] => Array
        (
            [o] => 
            [n] => replied,
        )

    [17] => Array
        (
            [o] => 
            [n] => so
        )

    [18] => Array
        (
            [o] => 
            [n] => can
        )

    [19] => you
    [20] => Array
        (
            [o] => reply,
            [n] => 
        )

    [21] => Array
        (
            [o] => so
            [n] => 
        )

    [22] => Array
        (
            [o] => can
            [n] => 
        )

    [23] => Array
        (
            [o] => you
            [n] => 
        )

    [24] => do
    [25] => it?
    [26] => Array
        (
            [o] => 
            [n] => Yes,
        )

    [27] => Array
        (
            [o] => 
            [n] => I
        )

    [28] => Array
        (
            [o] => 
            [n] => can!
        )

这就像一个简单的差异,但没有“+”和“-”,在简单解析后,两者都被替换为“o”(旧)和“n”(新)数组键。您可以使用以下函数来解析结果:

function format_response($diff_arr){
    $new = false;
    echo '<span class="old">';
    foreach($diff_arr as $item)
    {
        $content = '';
        if (!is_array($item)){
            $new = false;
            $content = $item;
        }
        else
            if (empty($item['o']) && !empty($item['n'])){
                $new = true;
                $content = $item['n'];
            }

        if($old_new != $new){
            if($new)
                echo '</span><span class="new">';
            else
                echo '</span><span class="old">';
        }

        echo $content . (!empty($content)?' ':'');

        $old_new = $new;
    }
    echo '</span>'; 
}

因此,您可以使用以下方法解析数组,而不是使用简单的“print_r”:

format_response(farray_diff(explode(' ', $str1), explode(' ', $str2)));

你会得到(按照例子)这样的东西:

<span class="old"></span><span class="new">I response in your text: </span><span class="old">This is a simple text </span><span class="new">(no so simple) </span><span class="old">that can </span><span class="new">be replied, so can </span><span class="old">you do it? </span><span class="new">Yes, I can! </span>

显然,要正确显示结果,您需要先定义 css “旧”和“新”类,但要有一些不同,pex: 不同的前景色:

<style>.old{color: #808080;}.new{color:#000000}</style>

对于 html 电子邮件,或者您可以修改 format_response 函数以显示非 html 电子邮件。

注意:如您所见,我的功能是免费软件,并遵循 GNU 通用公共许可证。

希望对你有帮助。

【讨论】:

  • 还没有机会尝试这个——但很快就会有
  • 好的!使用它,请给我反馈
【解决方案2】:

似乎 Gmail 正在对流行的“引用文本”标题进行一些精细的正则表达式匹配,即

-----原文-----
来自:...
发送:...
收件人:...
主题:...

,John Smith 写道:
...

________________
来自:...
发送:...
收件人:...
主题:...

而且他们实际上并不能很好地识别它们......

【讨论】:

    【解决方案3】:

    您总是可以使用 HTML 电子邮件并在 HTML cmets 中放置某种分隔符:

    <!-- **********SEPARATOR********** -->
    

    然后退回到一个简单的

    **********SEPARATOR**********
    

    如果用户不支持 HTML 电子邮件。您只需在您正在解析的电子邮件中查找后者,它应该在两种情况下(纯文本和 html)都可以正常工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-02-26
      • 1970-01-01
      • 1970-01-01
      • 2011-01-16
      • 2020-10-20
      • 1970-01-01
      • 2017-06-27
      • 1970-01-01
      相关资源
      最近更新 更多