如何使用JavaScript将文本的一部分包装在一个节点中
如何使用JavaScript将文本的一部分包装在一个节点中
我有一个具有挑战性的问题要解决。我正在编写一个脚本,该脚本以正则表达式作为输入。然后,该脚本在文档中找到与该正则表达式匹配的所有内容,并将每个匹配项包裹在自己的元素中。困难的部分是,文本是一个格式化的HTML文档,因此我的脚本需要在DOM中进行导航,并同时应用正则表达式于多个文本节点,同时确定如果需要的话在哪里分割文本节点。
例如,使用一个捕获以大写字母开头、以句号结尾的完整句子的正则表达式,该文档:
HTML is a language used to make websites. It was developed by CERN employees in the early 90s.
理想情况下将变为:
HTML is a language used to make websites. It was developed by CERN employees in the early 90s.
然后,该脚本应返回所有创建的元素的列表。
我已经有一些代码,可以找到所有文本节点,并将它们与整个文档中的位置和深度一起存储在列表中。你不需要真正理解那段代码来帮助我,它的递归结构可能有点令人困惑。但我不确定如何确定哪些元素应该包含在元素内。
function findTextNodes(node, depth = -1, start = 0) { let list = []; if (node.nodeType === Node.TEXT_NODE) { list.push({ node, depth, start }); } else { for (let i = 0; i < node.childNodes.length; ++i) { list = list.concat(findTextNodes(node.childNodes[i], depth+1, start)); if (list.length) { start += list[list.length-1].node.nodeValue.length; } } } return list; }
我想将所有文档变为一个字符串,通过它运行正则表达式,并使用列表找出哪些节点对应于哪些正则表达式匹配项,然后相应地分割文本节点。
但是,当我有一个像这样的文档时,就出现了一个问题:
This program is not stable yet. Do not use this in production yet.
有一个句子从标签外开始,但在标签内结束。现在,我不希望脚本将该链接分割为两个标签。在一个更复杂的文档中,这样做可能会破坏页面。代码可以将两个句子一起包装起来:
This program is not stable yet. Do not use this in production yet.
或者只是将每个部分分别包装在自己的元素中:
This program is not stable yet. Do not use this in production yet.
可以有一个参数来指定它应该做什么。我只是不确定如何判断何时将发生不可能的分割,并且如何从中恢复。
当我在子元素内部有空格时,另一个问题出现了:
This is a sentence.
从技术上讲,正则表达式匹配项会在句号后面、在标签的结束之前结束。然而,将空格视为匹配项的一部分并将其包装起来会更好:
This is a sentence.
而不是这样:
This is a sentence.
但这只是一个小问题。毕竟,我可以允许正则表达式包含额外的空格。
我知道这可能听起来像一个“帮我做”的问题,而不是我们每天在SO上看到的那种快速问题,但我已经被困在这个问题上一段时间了,这是我正在开发的一个开源库的最后障碍。如果你认为其他SE网站更适合这个问题,请引导我。