我有一个具有挑战性的问题要解决。我正在编写一个将正则表达式作为输入的脚本。然后,此脚本在文档中查找此正则表达式的所有匹配项,并将每个匹配项包装在其自己的 <span> 元素中。困难的部分是文本是一个格式化的 html 文档,所以我的脚本需要在 DOM 中导航并一次在多个文本节点上应用正则表达式,同时找出如果需要它必须在何处拆分文本节点。
例如,使用捕获以大写字母开头并以句点结尾的完整句子的正则表达式,此文档:
<p>
<b>HTML</b> is a language used to make <b>websites.</b>
It was developed by <i>CERN</i> employees in the early 90s.
<p>
会变成这样:
<p>
<span><b>HTML</b> is a language used to make <b>websites.</b></span>
<span>It was developed by <i>CERN</i> employees in the early 90s.</span>
<p>
然后脚本返回所有创建的跨度的列表。
我已经有一些代码可以找到所有的文本节点,并将它们连同它们在整个文档中的位置和深度一起存储在一个列表中。你真的不需要理解那些代码来帮助我,它的递归结构可能有点令人困惑。Ť他我不知道该怎么办第一部分是搞清楚哪些元素应包括在范围之内。
function SmartNode(node, depth, start) {
this.node = node;
this.depth = depth;
this.start = start;
}
function findTextNodes(node, depth, start) {
var list = [];
var start = start || 0;
depth = (typeof depth !== "undefined" ? depth : -1);
if(node.nodeType === Node.TEXT_NODE) {
list.push(new SmartNode(node, depth, start));
} else {
for(var 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;
}
我想我将从所有文档中创建一个字符串,通过它运行正则表达式并使用该列表查找对应于女巫正则表达式匹配的节点,然后相应地拆分文本节点。
但是当我有这样的文件时,问题就来了:
<p>
This program is <a href="beta.html">not stable yet. Do not use this in production yet.</a>
</p>
有一个句子从<a>
标签外开始,但在标签内结束。现在我不希望脚本将该链接拆分为两个标签。在更复杂的文档中,如果这样做,它可能会破坏页面。代码可以将两个句子包装在一起:
<p>
<span>This program is <a href="beta.html">not stable yet. Do not use this in production yet.</a></span>
</p>
或者只是将每个部分包装在自己的元素中:
<p>
<span>This program is </span>
<a href="beta.html">
<span>not stable yet.</span>
<span>Do not use this in production yet.</span>
</a>
</p>
可能有一个参数来指定它应该做什么。我只是不确定如何确定何时将发生不可能的削减,以及如何从中恢复。
当我在这样的子元素中有空格时会出现另一个问题:
<p>This is a <b>sentence. </b></p>
从技术上讲,正则表达式匹配将在句点之后、<b>
标签结束之前立即结束。但是,最好将空间视为匹配的一部分并将其包装如下:
<p><span>This is a <b>sentence. </b></span></p>
比这个:
<p><span>This is a </span><b><span>sentence.</span> </b></p>
但这是一个小问题。毕竟,我可以只允许在正则表达式中包含额外的空格。
我知道这听起来像是一个“为我做”的问题,而不是我们每天在 SO 上看到的那种快速问题,但我已经坚持了一段时间,这是一个开源库我正在尝试。解决这个问题是最后一个障碍。如果您认为另一个 SE 站点最适合此问题,请重定向我。