假设我有一个看起来像这样的HTML页面:
<html><body>
00123
<input value="00123">
00456
</body></html>
我想使用javascript / jQuery使它看起来像这样:
<html><body>
<a href="#00123">00123</a>
<input value="00123">
<a href="#00456">00456</a>
</body></html>
基本上我想用HTML锚标签在文档中包装正则表达式匹配的普通字符串。在这个例子中,我想做类似的事情:
$('body').html($('body').html().replace(/(00\d+)/, '<a href="#$1">$1</a>'));
使用此示例查看jsFiddle:http://jsfiddle.net/NATnr/2/
此解决方案的问题是input
元素内的文本已匹配并替换。
有没有人知道如何使用javascript / jQuery以这种方式匹配和替换文档中的纯文本?
答案 0 :(得分:8)
filtering contents()
nodeType Fiddle仅{+ 3}}获取文本节点,然后用jQuery生成的锚元素替换它们(这些中的任何额外文本)节点将保留为文本节点):
body
如您所知,通常使用Regex解析HTML并不是一个好主意(注意global modifier,它们是邪恶的),但是如果您要分离要解析的HTML的一部分,则遵循一个相对简单的模式,它是一个可行的选择。
编辑:在您的正则表达式中包含$('body').contents().filter(function() {
return this.nodeType === 3;
}).each(function() {
$(this).replaceWith($(this).text().replace(/(00\d+)/g, '<a href="#$1">$1</a>'));
});
标记({{3}}),以便在单个文本节点中匹配多个锚点。
答案 1 :(得分:5)
最终解决方案最终看起来像这样:
jQuery.fn.linker = function () {
$(this).contents()
.filter(function() { return this.nodeType != Node.TEXT_NODE; })
.each(function () { $(this).linker(); });
$(this).contents()
.filter(function() { return this.nodeType == Node.TEXT_NODE; })
.each(function () {
$(this).replaceWith(
$(this).text().replace(/(00\d+)/g, '<a href="#$1">$1</a>')
);
});
}
$(document).ready(function () {
$('body').linker();
});
请参阅此处的jsFiddle:http://jsfiddle.net/fr4AL/4/
感谢:
答案 2 :(得分:0)
这是来自bobince问题的相关答案:
你不想用正则表达式处理HTML。分配.html()的大块也是坏消息;除了序列化和重新分析大量HTML的性能缺点之外,您还将丢失不可重复的数据,如事件侦听器,表单数据和JS属性/引用。
这是一个允许RegExp模式匹配的纯JavaScript / DOM。 jQuery在这里并没有真正给你太多帮助,因为选择器只能选择元素,':contains'选择器是递归的,所以对我们来说不太有用。
// Find text in descendents of an element, in reverse document order
// pattern must be a regexp with global flag
//
function findText(element, pattern, callback) {
for (var childi= element.childNodes.length; childi-->0;) {
var child= element.childNodes[childi];
if (child.nodeType==1) {
findText(child, pattern, callback);
} else if (child.nodeType==3) {
var matches= [];
var match;
while (match= pattern.exec(child.data))
matches.push(match);
for (var i= matches.length; i-->0;)
callback.call(window, child, matches[i]);
}
}
}
findText(document.body, /\bBuyNow\b/g, function(node, match) {
var span= document.createElement('span');
span.className= 'highlight';
node.splitText(match.index+6);
span.appendChild(node.splitText(match.index+3));
node.parentNode.insertBefore(span, node.nextSibling);
});
答案 3 :(得分:0)
给它一个旋转......更干净! ;)
$('input').each(function() {
var temp;
temp = $(this).val();
$(this).before('<a href="#' + temp +'">' +temp+ '</a>');
});
$('body').contents().filter(function() {return this.nodeType == 3;}).remove();