【问题标题】:Better way of extracting text from HTML in Javascript在 Javascript 中从 HTML 中提取文本的更好方法
【发布时间】:2025-12-31 03:55:12
【问题描述】:

我正在尝试使用 container.innerText || container.textContent 从 HTML 字符串中抓取文本,其中 container 是我要从中提取文本的元素。

通常,我要提取的文本位于<p> 标记中。所以以下面的 HTML 为例:

<div id="container">
    <p>This is the first sentence.</p>
    <p>This is the second sentence.</p>
</div>

使用

var container = document.getElementById("container");
var text = container.innerText || container.textContent; // the text I want

将返回This is the first sentence.This is the second sentence.,第一个句点和第二个句子的开头之间没有空格。

我的总体目标是使用 Stanford CoreNLP 解析文本,但它的解析器无法检测到这些是 2 个句子,因为它们没有被空格分隔。有没有更好的方法从 HTML 中提取文本,使句子用空格字符分隔?

我正在解析的 HTML 将在 &lt;p&gt; 标记中包含我最想要的文本,但 HTML 还可能包含 &lt;img&gt;&lt;a&gt; 以及嵌入在 &lt;p&gt; 标记之间的其他标记。

【问题讨论】:

  • jQuery 标签有什么用途吗?

标签: javascript jquery html regex html-parsing


【解决方案1】:

作为一个肮脏的黑客,尝试使用这个:

container.innerHTML.replace(/<.*?>/g," ").replace(/ +/g," ");

这会将所有标签替换为一个空格,然后将多个空格合并为一个。

请注意,如果属性值中有&gt;,这会搞砸你。避免这个问题需要更精细的解析,例如遍历所有文本节点并将它们放在一起。


更长但更健壮的方法:

function recurse(result, node) {
    var c = node.childNodes, l = c.length, i;
    for( i=0; i<l; i++) {
        if( c[i].nodeType == 3) result += c.nodeValue + " ";
        if( c[i].nodeType == 1) result = recurse(result, c[i]);
    }
    return result;
}
recurse(container);

假设我没有犯愚蠢的错误,这将对文本节点执行深度优先搜索,并将其内容附加到结果中。

【讨论】:

  • 我找到了一种解决这个问题的 hacky 方法,它可以处理空格和 &gt; 符号,但我希望有更多合法的方式来完成这项任务。如果我找不到,那我想这就足够了。
  • 你有花式递归。这看起来比我计划提取文本的方式更好。我会试试这个。
【解决方案2】:

jQuery 有 text() 方法可以满足你的需求。这对你有用吗?

我不确定它是否适合您容器中的所有内容,但它适用于我的示例。它还将获取&lt;a&gt;-tag 的文本并将其附加到文本中。

2020 年 12 月 20 日更新

如果你没有使用 jQuery。你可以像这样用 vanilla js 实现text 方法:

const nodes = Array.from(document.querySelectorAll("#container"));
const text = nodes
  .filter((node) => !!node.textContent)
  .map((node) => node.textContent)
  .join(" ");

使用querySelectorAll("#container") 获取容器中的每个节点。使用Array.from,这样我们就可以使用过滤器、映射和连接等数组方法。

最后,通过过滤掉没有textContent的元素来生成文本。然后使用map获取每个文本,并使用join在文本之间添加空格分隔符。

$(function() {
    var textToParse = $('#container').text();
    $('#output').html(textToParse);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
    <p>This is the first sentence.</p>
    <p>This is the second sentence.</p>
    <img src="http://placehold.it/200x200" alt="Nice picture"></img>
    <p>Third sentence.</p>
</div>

<h2>output:</h2>
<div id="output"></div>

【讨论】:

  • 这个答案似乎是从 HTML 中获取文本的最有效方法,而不必求助于任何廉价的黑客,因为我可以用这个提取由空格分隔的句子。实际上,我对使用 jQuery 有点犹豫,因为我正在使用它来使用 TinyMCE API 制作一个 Wordpress 插件,尽管我不确定如何将 jQuery 加载到我正在编写的脚本中。我认为这是我的问题的正确答案,尽管我现在要了解如何将 jQuery 加载到我的 Wordpress 插件中。谢谢。
【解决方案3】:

您可以使用以下函数来提取和处理如图所示的文本。它基本上遍历目标元素的所有子节点和子节点的子节点等等......在适当的点添加spaces

function getInnerText( sel ) {
    var txt = '';
    $( sel ).contents().each(function() {
        var children = $(this).children();
        txt += ' ' + this.nodeType === 3 ? this.nodeValue : children.length ? getInnerText( this ) : $(this).text();
    });
    return txt;
}

function getInnerText( sel ) {
  var txt = '';
  $( sel ).contents().each(function() {
    var children = $(this).children();
    txt += ' ' + this.nodeType === 3 ? 
      this.nodeValue : children.length ? 
      getInnerText( this ) : $(this).text();
  });
  return txt;
}

alert( getInnerText( '#container' ) );
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="container">
    Some other sentence
    <p>This is the first sentence.</p>
    <p>This is the second sentence.</p>
</div>

【讨论】:

    【解决方案4】:

    您可以使用 jQuery 来遍历元素。


    这是代码:

    $(document).ready(function()
    {
        var children = $("#container").find("*");
        var text = "";
    
        while (children.html() != undefined)
        {
            text += children.html()+"\n";
            children = children.next();
        }
    
        alert(text);
    });
    



    这是小提琴http://jsfiddle.net/69wezyc5/

    【讨论】: