我要做的是在字符串中查找所有匹配项,然后将它们包装在样式化的span标记中。我提出的解决方案使用递归,这是代码:
function foo(node, pattern) {
// alert(node.nodeValue);
// alert(node.nodeValue + '\n' + pattern.test(node.nodeValue));
if (pattern.test(node.nodeValue)) {
// alert(node.nodeValue);
var span = document.createElement('span');
var text = document.createTextNode(RegExp.rightContext);
span.className = 'someClass';
span.innerHTML = RegExp.$1;
node.nodeValue = RegExp.leftContext;
node.parentNode.insertBefore(span, node.nextSibling);
node.parentNode.insertBefore(text, span.nextSibling);
foo(text, pattern);
}
return;
}
在这个小提琴中看到它的实际效果:http://jsfiddle.net/Umcaf/
我遇到的问题是它不会标出“测试”一词的所有实例。如果您使用警报语句,您会注意到一些奇怪的行为(无论如何,这对我来说很奇怪)。如果您取消注释第一个警报,您将看到我想要测试的所有正确字符串,但即使最后一个字符串中包含“test”一词,pattern.test(node.nodeValue)
也不会产生'true'。这非常令人困惑。
当然,我想出了第二个警告声明。当使用第二个警告语句时,它会警告不正确的字符串(并且我的意思是它不会警告第一个完整的字符串并添加最后一个仅包含空格的字符串)并且第一次出现'test'isn'标记,但最后两个是!
我对正则表达式相当新,但我认为直到现在我已经理解它们了。谁能解释一下这里发生了什么?
答案 0 :(得分:3)
只需从你的正则表达式中删除g,问题就消失了。
foo(node, /(test)/i);
你的正则表达式中有一个全局匹配标志。每次调用test()时,它都会向前推动指针。
您可以在这里阅读更多内容:
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/RegExp/test
与exec(或与exec一起)一样,多次调用 在同一个全局正则表达式实例上将超越 上一场比赛。
答案 1 :(得分:3)
clowwindy提供了解决方案。
我想指出另一种达到目标的方法(您可以保留g
修饰符):
function bar(node, pattern) {
node.parentNode.innerHTML =
node.nodeValue.replace(pattern,'<span class="someClass">$1</span>');
}