86

我使用TinyMCE允许在我的网站中使用最少的文本格式。从生成的 HTML 中,我想将其转换为电子邮件的纯文本。我一直在使用一个名为html2text的类,但它确实缺乏对 UTF-8 的支持,等等。然而,我确实喜欢它将某些 HTML 标记映射到纯文本格式——比如在 HTML 中以前具有 <i> 标记的文本周围加上下划线。

有没有人使用类似的方法在 PHP 中将 HTML 转换为纯文本?如果是这样:您是否推荐任何我可以使用的第三方课程?或者你如何最好地解决这个问题?

4

14 回答 14

107

使用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);

虽然不完整,但它是开源的,欢迎贡献。

其他转换脚本的问题:

于 2010-04-02T00:32:39.087 回答
29

这是另一个解决方案:

$cleaner_input = strip_tags($text);

有关清理功能的其他变体,请参阅:

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

于 2013-06-25T16:58:55.740 回答
14

使用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。

请注意商业用途的限制。

于 2010-03-17T21:52:00.420 回答
13

有可靠的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)));

?>
于 2009-12-10T23:07:44.503 回答
9

您可以使用带有 -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";
}
于 2012-03-08T02:32:04.660 回答
8

你可以测试这个功能

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);
}
于 2013-12-13T03:40:18.467 回答
6

我没有找到任何适合的现有解决方案 - 简单的 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
于 2016-11-21T15:34:28.547 回答
5
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

于 2017-08-11T08:11:26.287 回答
4

如果您想转换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; htmlspecialchars_decode 之类的东西html_entity_decode 之类的东西&amp; 转换之类的东西'&lt; strip_tags 删除任何剩余的 HTML 标签。

于 2018-05-15T14:36:04.583 回答
3

Markdownify将 HTML 转换为 Markdown,这是该站点上使用的纯文本格式系统。

于 2011-12-28T10:14:19.470 回答
2

我遇到了与 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 代码/名称(例如)或不成对引号(例如)的情况,脚本http://www.chuggnutt.com/html2text.php不能开箱即用。&auml;<p>25" Monitor</p>

  • 脚本https://github.com/soundasleep/html2text无法隐藏或分组文本末尾的链接,这使得通常的 HTML 页面在纯文本格式时看起来很臃肿;自定义代码以特殊处理如何完成转换并不像简单地在html2text_roundcube.

于 2016-11-24T16:10:53.993 回答
2

对于 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);
于 2019-09-03T18:39:08.273 回答
1

我刚刚找到了一个 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?
于 2012-05-16T21:17:33.780 回答
1

如果您不想完全剥离标签并将内容保留在标签内,您可以使用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!

这种方法的一个优点是它不需要任何外部包。

于 2018-04-02T17:02:01.687 回答