簡體   English   中英

將 HTML 轉換為 PHP 中的純文本以用於電子郵件

[英]Converting HTML to plain text in PHP for e-mail

我使用TinyMCE來允許在我的站點中最小化文本格式。 從生成的 HTML 中,我想將其轉換為電子郵件的純文本。 我一直在使用一個名為html2text的類,但除其他外,它確實缺乏對 UTF-8 的支持。 然而,我確實喜歡它將某些 HTML 標簽映射到純文本格式——比如在以前在 HTML 中有 <i> 標簽的文本周圍放置下划線。

有沒有人使用類似的方法在 PHP 中將 HTML 轉換為純文本? 如果是這樣:您是否推薦我可以使用的任何第三方類? 或者你如何最好地解決這個問題?

使用html2text (示例HTML文本),在Eclipse Public License下獲得許可 它使用 PHP 的 DOM 方法從 HTML 加載,然后迭代生成的 DOM 以提取純文本。 用法:

// when installed using the Composer package
$text = Html2Text\Html2Text::convert($html);

// usage when installed using html2text.php
require('html2text.php');
$text = convert_html_to_text($html);

雖然不完整,但它是開源的,歡迎貢獻。

其他轉換腳本的問題:

這是另一種解決方案:

$cleaner_input = strip_tags($text);

有關消毒功能的其他變體,請參閱:

https://github.com/ttodua/useful-php-scripts/blob/master/filter-php-variable-sanitize.php

使用DOMDocument從 HTML 轉換為文本是一個可行的解決方案。 考慮 HTML2Text,它需要 PHP5:

關於 UTF-8,“howto”頁面上的文章指出:

PHP 本身對 unicode 的支持很差,而且它並不總是正確處理 utf-8。 盡管 html2text 腳本使用 unicode-safe 方法(不需要 mbstring 模塊),但它不能總是處理 PHP 自己的編碼處理。 PHP 並不真正理解 unicode 或 utf-8 之類的編碼,而是使用系統的基本編碼,這往往是 ISO-8859 系列之一。 因此,在您的文本編輯器中看起來像是有效字符的 utf-8 或單字節字符很可能會被 PHP 誤解。 因此,即使您認為將有效字符輸入到 html2text 中,也可能不是。

作者提供了幾種解決此問題的方法,並指出 HTML2Text 的第 2 版(使用 DOMDocument)支持 UTF-8。

請注意商業用途的限制。

有值得信賴的strip_tags函數。 不過也不是很漂亮。 它只會消毒。 您可以將它與字符串替換結合使用以獲得您喜歡的下划線。


<?php
// to strip all tags and wrap italics with underscore
strip_tags(str_replace(array("<i>", "</i>"), array("_", "_"), $text));

// to preserve anchors...
str_replace("|a", "<a", strip_tags(str_replace("<a", "|a", $text)));

?>

您可以使用帶有 -stdin 和 -dump 選項的 lynx 來實現:

<?php
$descriptorspec = array(
   0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
   1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
   2 => array("file", "/tmp/htmp2txt.log", "a") // stderr is a file to write to
);

$process = proc_open('lynx -stdin -dump 2>&1', $descriptorspec, $pipes, '/tmp', NULL);

if (is_resource($process)) {
    // $pipes now looks like this:
    // 0 => writeable handle connected to child stdin
    // 1 => readable handle connected to child stdout
    // Any error output will be appended to htmp2txt.log

    $stdin = $pipes[0];
    fwrite($stdin,  <<<'EOT'
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
 <title>TEST</title>
</head>
<body>
<h1><span>Lorem Ipsum</span></h1>

<h4>"Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit..."</h4>
<h5>"There is no one who loves pain itself, who seeks after it and wants to have it, simply because it is pain..."</h5>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque et sapien ut erat porttitor suscipit id nec dui. Nam rhoncus mauris ac dui tristique bibendum. Aliquam molestie placerat gravida. Duis vitae tortor gravida libero semper cursus eu ut tortor. Nunc id orci orci. Suspendisse potenti. Phasellus vehicula leo sed erat rutrum sed blandit purus convallis.
</p>
<p>
Aliquam feugiat, neque a tempus rhoncus, neque dolor vulputate eros, non pellentesque elit lacus ut nunc. Pellentesque vel purus libero, ultrices condimentum lorem. Nam dictum faucibus mollis. Praesent adipiscing nunc sed dui ultricies molestie. Quisque facilisis purus quis felis molestie ut accumsan felis ultricies. Curabitur euismod est id est pretium accumsan. Praesent a mi in dolor feugiat vehicula quis at elit. Mauris lacus mauris, laoreet non molestie nec, adipiscing a nulla. Nullam rutrum, libero id pellentesque tempus, erat nibh ornare dolor, id accumsan est risus at leo. In convallis felis at eros condimentum adipiscing aliquam nisi faucibus. Integer arcu ligula, porttitor in fermentum vitae, lacinia nec dui.
</p>
</body>
</html>
EOT
    );
    fclose($stdin);

    echo stream_get_contents($pipes[1]);
    fclose($pipes[1]);

    // It is important that you close any pipes before calling
    // proc_close in order to avoid a deadlock
    $return_value = proc_close($process);

    echo "command returned $return_value\n";
}

你可以測試這個功能

function html2text($Document) {
    $Rules = array ('@<script[^>]*?>.*?</script>@si',
                    '@<[\/\!]*?[^<>]*?>@si',
                    '@([\r\n])[\s]+@',
                    '@&(quot|#34);@i',
                    '@&(amp|#38);@i',
                    '@&(lt|#60);@i',
                    '@&(gt|#62);@i',
                    '@&(nbsp|#160);@i',
                    '@&(iexcl|#161);@i',
                    '@&(cent|#162);@i',
                    '@&(pound|#163);@i',
                    '@&(copy|#169);@i',
                    '@&(reg|#174);@i',
                    '@&#(d+);@e'
             );
    $Replace = array ('',
                      '',
                      '',
                      '',
                      '&',
                      '<',
                      '>',
                      ' ',
                      chr(161),
                      chr(162),
                      chr(163),
                      chr(169),
                      chr(174),
                      'chr()'
                );
  return preg_replace($Rules, $Replace, $Document);
}

我沒有找到任何適合的現有解決方案 - 簡單的 HTML 電子郵件到簡單的純文本文件。

我已經打開了這個存儲庫,希望它可以幫助某人。 麻省理工學院許可證,順便說一句:)

https://github.com/RobQuistNL/SimpleHtmlToText

例子:

$myHtml = '<b>This is HTML</b><h1>Header</h1><br/><br/>Newlines';
echo (new Parser())->parseString($myHtml);

返回:

**This is HTML**
### Header ###


Newlines
public function plainText($text)
{
    $text = strip_tags($text, '<br><p><li>');
    $text = preg_replace ('/<[^>]*>/', PHP_EOL, $text);

    return $text;
}

$text = "string 1<br>string 2<br/><ul><li>string 3</li><li>string 4</li></ul><p>string 5</p>";

echo planText($text);

輸出
字符串 1
字符串 2
字符串 3
字符串 4
字符串 5

如果您想轉換HTML 特殊字符,而不僅僅是刪除它們以及剝離內容並准備純文本,那么這就是對我有用的解決方案......

function htmlToPlainText($str){
    $str = str_replace('&nbsp;', ' ', $str);
    $str = html_entity_decode($str, ENT_QUOTES | ENT_COMPAT , 'UTF-8');
    $str = html_entity_decode($str, ENT_HTML5, 'UTF-8');
    $str = html_entity_decode($str);
    $str = htmlspecialchars_decode($str);
    $str = strip_tags($str);

    return $str;
}

$string = '<p>this is (&nbsp;) a test</p>
<div>Yes this is! &amp; does it get "processed"? </div>'

htmlToPlainText($string);
// "this is ( ) a test. Yes this is! & does it get processed?"`

html_entity_decode w/ENT_QUOTES | ENT_XML1 轉換諸如&#39;類的東西&#39; htmlspecialchars_decode 轉換諸如&amp;東西&amp; html_entity_decode 轉換諸如'&lt; 和 strip_tags 刪除任何剩余的 HTML 標簽。

Markdownify將 HTML 轉換為 Markdown,這是本網站上使用的純文本格式系統。

我遇到了與 OP 相同的問題,並且從上面的最佳答案中嘗試了一些解決方案並沒有證明對我的場景有效。 最后看看為什么。

相反,我發現了這個有用的腳本,為了避免混淆,我們將其html2text_roundcube ,在 GPL 下可用:

它實際上是已經提到的腳本的更新版本 - http://www.chuggnutt.com/html2text.php - 由 RoundCube 郵件更新。

用法:

$h2t = new \Html2Text\Html2Text('Hello, &quot;<b>world</b>&quot;');
echo $h2t->getText(); // prints Hello, "WORLD"

為什么html2text_roundcube被證明比其他的更好:

  • 對於具有特殊 HTML 代碼/名稱(例如&auml; )或不成對引號(例如<p>25" Monitor</p> )的情況,腳本http://www.chuggnutt.com/html2text.php無法開箱即用<p>25" Monitor</p> )。

  • 腳本https://github.com/soundasleep/html2text沒有選項隱藏或分組文本末尾的鏈接,使普通的 HTML 頁面在純文本格式時看起來因鏈接而臃腫; 自定義代碼以對如何完成轉換進行特殊處理並不像簡單地在html2text_roundcube編輯數組那么簡單。

對於 utf-8 中的文本,它對我有用 mb_convert_encoding。 要處理所有內容而不考慮錯誤,請確保使用“@”。

我使用的基本代碼是:

$dom = new DOMDocument();
@$dom->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'));

$body = $dom->getElementsByTagName('body')->item(0);
echo $body->textContent;

如果你想要更高級的東西,你可以迭代分析節點,但是你會遇到很多空白的問題。

我已經根據我在這里所說的內容實現了一個轉換器。 有興趣的可以到git https://github.com/kranemora/html2text下載

它可以作為參考來制作你的

你可以這樣使用它:

$html = <<<EOF
<p>Welcome to <strong>html2text<strong></p>
<p>It's <em>works</em> for you?</p>
EOF;

$html2Text = new \kranemora\Html2Text\Html2Text;
$text = $html2Text->convert($html);

Markdownify對我來說很棒! 必須提及的內容:它完全支持utf-8,這是我為什么要尋找除html2text之外的另一種解決方案的主因(此線程前面提到的內容)。

我剛剛找到了一個 PHP 函數“strip_tags()”,它在我的情況下工作。

我試圖轉換以下 HTML :

<p><span style="font-family: 'Verdana','sans-serif'; color: black; font-size: 7.5pt;">&nbsp;</span>Many  practitioners are optimistic that the eyeglass and contact lens  industry will recover from the recent economic storm. Did your practice  feel its affects?&nbsp; Statistics show revenue notably declined in 2008 and  2009. But interestingly enough, those that monitor these trends state  that despite the industry's lackluster performance during this time,  revenue has grown at an average annual rate&nbsp;of 2.2% over the last five  years, to $9.0 billion in 2010.&nbsp; So despite the downturn, how were we  able to manage growth as an industry?</p>

應用 strip_tags() 函數后,我得到了以下輸出:

&amp;nbsp;Many  practitioners are optimistic that the eyeglass and contact lens  industry will recover from the recent economic storm. Did your practice  feel its affects?&amp;nbsp; Statistics show revenue notably declined in 2008 and  2009. But interestingly enough, those that monitor these trends state  that despite the industry&#039;s lackluster performance during this time,  revenue has grown at an average annual rate&amp;nbsp;of 2.2% over the last five  years, to $9.0 billion in 2010.&amp;nbsp; So despite the downturn, how were we  able to manage growth as an industry?

如果您不想完全剝離標簽並將內容保留在標簽內,您可以使用DOMDocument並像這樣提取根節點的textContent

function html2text($html) {
    $dom = new DOMDocument();
    $dom->loadHTML("<body>" . strip_tags($html, '<b><a><i><div><span><p>') . "</body>");
    $xpath = new DOMXPath($dom);
    $node = $xpath->query('body')->item(0);
    return $node->textContent; // text
}

$p = 'this is <b>test</b>. <p>how are <i>you?</i>. <a href="#">I\'m fine!</a></p>';
print html2text($p);
// this is test. how are you?. I'm fine!

這種方法的一個優點是它不需要任何外部包。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM