gpt4 book ai didi

javascript - 纯正则表达式解决方案,用于在无法依赖 document.createElement 的环境中从 HTML 字符串获取文本内容?

转载 作者:行者123 更新时间:2023-12-01 00:37:51 26 4
gpt4 key购买 nike

我有 HTML 字符串,我想获取元素的文本内容,但我正在工作的环境不允许我创建一个元素,然后简单地获取 innerText ,例如:

const span = document.createElement('span');
span.innerHTML = myHtmlString;
const justTheText = span.innerText;

仅使用正则表达式可以做到这一点吗?我已经进行了多次尝试,但从未想出可行的解决方案。标签的嵌套性质使我获得了 90% 的工作解决方案,但我找不到任何方法来处理这方面。 (抱歉没有提供我的一次尝试的示例,我只是在几个月前放弃它并花了几天时间后才重新审视这个问题。)

我也从未找到解决方法,无论是否使用正则表达式,因为 99.999% 的情况下,正确的答案是使用我上面发布的代码,而这正是给出的答案。

(我也愿意接受非正则表达式解决方案)

<小时/>

编辑:

HTML 字符串示例:

<div>
<p class="someclass">
Some plain text
<strong>
and some bold
</strong>
</p>
</div>

通过正则表达式从单个 html 元素获取文本很容易,但我不确定是否有任何方法可以处理嵌套以获得结果:一些纯文本和一些粗体 - 如果有这是我不知道的一种方式,但正则表达式的一些最高级的功能仍然超出了我的理解范围。

最佳答案

您始终可以获得标签的内容。
从内容中删除内部标签,然后 trim 空白。

在示例中,我们使用 div 标签,但您也可以使用
任何带有属性的标签,例如下面的 p 标签。

这是一个 JS 示例:

var tag = "div";  
// var tag = "p"; // <= try this; works with tags with attributes as well

var rxTagContent = new RegExp( "<" + tag + "(?:\\s*>|\\s+(?=((?:\"[\\S\\s]*?\"|'[\\S\\s]*?'|(?:(?!/>)[^>])?)+))\\1>)((?:(?=(<(?:(?:(?:(script|style|object|embed|applet|noframes|noscript|noembed)(?:\\s+(?:\"[\\S\\s]*?\"|'[\\S\\s]*?'|(?:(?!/>)[^>])?)+)?\\s*>)[\\S\\s]*?</\\4\\s*(?=>))|(?:/?[\\w:]+\\s*/?)|(?:[\\w:]+\\s+(?:\"[\\S\\s]*?\"|'[\\S\\s]*?'|[^>]?)+\\s*/?)|\\?[\\S\\s]*?\\?|(?:!(?:(?:DOCTYPE[\\S\\s]*?)|(?:\\[CDATA\\[[\\S\\s]*?\\]\\])|(?:--[\\S\\s]*?--)|(?:ATTLIST[\\S\\s]*?)|(?:ENTITY[\\S\\s]*?)|(?:ELEMENT[\\S\\s]*?))))>|[\\S\\s]))\\3)*?)</" + tag + "\\s*>", "g" );

var rxRmvInnerTags =
/<(?:(?:(?:(script|style|object|embed|applet|noframes|noscript|noembed)(?:\s+(?:"[\S\s]*?"|'[\S\s]*?'|(?:(?!\/>)[^>])?)+)?\s*>)[\S\s]*?<\/\1\s*(?=>))|(?:\/?[\w:]+\s*\/?)|(?:[\w:]+\s+(?:"[\S\s]*?"|'[\S\s]*?'|[^>]?)+\s*\/?)|\?[\S\s]*?\?|(?:!(?:(?:DOCTYPE[\S\s]*?)|(?:\[CDATA\[[\S\s]*?\]\])|(?:--[\S\s]*?--)|(?:ATTLIST[\S\s]*?)|(?:ENTITY[\S\s]*?)|(?:ELEMENT[\S\s]*?))))>/g;

var rxWspTrim = /\s+/g;

////////////////////////////////////////////////
//
var html =
"<div>\n" +
" <p class=\"someclass\">\n" +
" Some plain text \n" +
" <strong>\n" +
" and some bold\n" +
" </strong>\n" +
" </p>\n" +
"</div>\n";

var match;

while ( match = rxTagContent.exec( html ) )
{
var cont = match[2]; // group 2 is content
var clean = cont.replace( rxRmvInnerTags, "" );
var trim = clean.replace( rxWspTrim, " " );

console.log ("content = " + cont );
console.log ("clean and trim = \n" + trim );
}

这是构建的标签内容正则表达式的扩展、可读版本。

请注意,此正则表达式和删除内部标记的正则表达式是
稍微复杂一点。如果您需要有关
的具体信息他们是如何工作的,请告诉我。我通常每隔几天出现一次,
有时一两周取决于我的评论有多少
正在被管理员删除...

更新:修改正则表达式以避免匹配结束标记文本
如果它恰好位于 CDATA 内或者即使它是另一个 CDATA 的一部分
标签的值,或者即使它位于脚本等不可见内容中。

例如,下面的内容将正确匹配。

请注意,唯一缺少的是嵌套标签的能力。
这是 JavaScript 不可能的。正则表达式可用于
一次查找标签和内容以进行完全自定义的解析。
但那是另一回事了。

这将找到第一个开始标记和第一个结束标记。
它仍然可以进一步修改 1 步来查找未嵌套
如果需要打开/关闭标记,则需要一个简单的添加断言。

另请注意,这不会阻止匹配 open 标记
如果它恰好位于 CDATA 或上述其他内容内。
这是可以避免的,但需要扩展 tag 正则表达式并在 while() 循环中进行检查以超越这些。
让我知道您是否需要这个(或者我可以在
中添加它)一天左右。我不希望事情太过失控),但这是可能的。

<tag> 

Some content
more
and more

<script>
var xyz;
var tag = "</tag>";
</script>

<![CDATA[ </tag> asdfasdf]]>

</tag>

https://regex101.com/r/Bs4ySe/1

 <tag
(?:
\s* >
| \s+
(?=
( # (1 start)
(?:
" [\S\s]*? "
| ' [\S\s]*? '
| (?:
(?! /> )
[^>]
)?
)+
) # (1 end)
)
\1 >
)
( # (2 start)
(?:
(?=
( # (3 start)

<(?:(?:(?:(script|style|object|embed|applet|noframes|noscript|noembed)(?:\s+(?:"[\S\s]*?"|'[\S\s]*?'|(?:(?!/>)[^>])?)+)?\s*>)[\S\s]*?</\4\s*(?=>))|(?:/?[\w:]+\s*/?)|(?:[\w:]+\s+(?:"[\S\s]*?"|'[\S\s]*?'|[^>]?)+\s*/?)|\?[\S\s]*?\?|(?:!(?:(?:DOCTYPE[\S\s]*?)|(?:\[CDATA\[[\S\s]*?\]\])|(?:--[\S\s]*?--)|(?:ATTLIST[\S\s]*?)|(?:ENTITY[\S\s]*?)|(?:ELEMENT[\S\s]*?))))>
| [\S\s]
) # (3 end)
)
\3
)*?
) # (2 end)
</tag \s* >

关于javascript - 纯正则表达式解决方案,用于在无法依赖 document.createElement 的环境中从 HTML 字符串获取文本内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57948276/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com