Javascript jQuery:如何在锚标记中包装正则表达式匹配的纯文本?
假设我有一个如下所示的HTML页面:Javascript jQuery:如何在锚标记中包装正则表达式匹配的纯文本?,javascript,jquery,html,regex,Javascript,Jquery,Html,Regex,假设我有一个如下所示的HTML页面: <html><body> 00123 <input value="00123"> 00456 </body></html> <html><body> <a href="#00123">00123</a> <input value="00123"> <a href="#00456">00456</a> </bo
<html><body>
00123
<input value="00123">
00456
</body></html>
<html><body>
<a href="#00123">00123</a>
<input value="00123">
<a href="#00456">00456</a>
</body></html>
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();
});
00123
00456
我想使用javascript/jQuery使其看起来像这样:
<html><body>
00123
<input value="00123">
00456
</body></html>
<html><body>
<a href="#00123">00123</a>
<input value="00123">
<a href="#00456">00456</a>
</body></html>
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();
});
本质上,我想在文档中用HTML锚定标记包装正则表达式匹配的普通字符串。在本例中,我希望执行以下操作:
$('body').html($('body').html().replace(/(00\d+)/, '<a href="#$1">$1</a>'));
$('body').html($('body').html().replace(/(00\d+/,''));
请参见带有此示例的JSFIDLE:
此解决方案的问题是,input
元素中的文本被匹配和替换
有人知道如何使用javascript/jQuery以这种方式仅匹配和替换文档中的纯文本吗?这来自bobince对一个问题的相关回答: 你不想用正则表达式处理HTML是对的。分配大量的.html()也是个坏消息;除了序列化和重新分析大量HTML的性能缺陷外,还将丢失不可序列化的数据,如事件侦听器、表单数据和JS属性/引用 下面是一个简单的JavaScript/DOM,它允许一个RegExp模式匹配。jQuery在这里并没有给您太多帮助,因为选择器只能选择元素,而且“:contains”选择器是递归的,所以对我们来说不是太有用 尝试使用
body
,只获取文本节点,然后用jQuery生成的锚元素替换它们(这些节点中的任何额外文本都将保留为文本节点):
$('body').contents().filter(函数(){
返回this.nodeType==3;
}).each(函数({
$(this).replaceWith($(this).text().replace(/(00\d+)/g',);
});
正如您所知,使用正则表达式解析HTML通常不是一个好主意(注意,它们是有害的),但是如果您分离出要解析的HTML的一部分,并且它遵循一个相对简单的模式,那么这是一个可行的选择
edit:在正则表达式中包含
g
标志(),以允许在单个文本节点中匹配多个锚。尝试一下。。。。更干净!!;)
$('input')。每个(函数(){
无功温度;
temp=$(this.val();
$(本)。在('')之前;
});
$('body').contents().filter(函数(){返回this.nodeType==3;}).remove();
最终的解决方案是这样的:
<html><body>
00123
<input value="00123">
00456
</body></html>
<html><body>
<a href="#00123">00123</a>
<input value="00123">
<a href="#00456">00456</a>
</body></html>
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();
});
jQuery.fn.linker=函数(){
$(this.contents())
.filter(函数(){返回this.nodeType!=Node.TEXT_Node;})
.each(函数(){$(this).linker();});
$(this.contents())
.filter(函数(){返回this.nodeType==Node.TEXT_Node;})
.每个(功能){
$(此)。替换为(
$(this).text().replace(/(00\d+)/g'')
);
});
}
$(文档).ready(函数(){
$('body').linker();
});
请参见此处工作的JSFIDLE:
感谢:
:)
小提琴中的.isbnlink()
应该是.linker()
我猜(或者你忘了包含扩展名),包装全文节点可能会有额外的空白,所以请花点时间查看这些节点+不过,对于很棒的插件代码来说,这是1。如果需要删除那些多余的空格,可以在href
中使用$.trim($(this).text())
。@fabriciomatté感谢您的提示。实际上我正在努力解决那个空白问题。我想我现在明白了。我用我最后得到的编辑了我的答案。为了只改变匹配的子字符串,我必须构造一个新的DOM元素。看起来不错<代码>=]但有一件事,重复的id(带有id=“link”
的多个span
s)是无效的标记(意味着它不会在w3c验证器上验证,如果您尝试使用jQuery或CSS的链接
选择器,您可能会遇到问题),当您向提供HTML字符串时,jQuery也会自动为您进行解析。我删除了重复的ID并简化了DOM解析部分:。@fabriciomatté正确解析HTML的replace做得很好!实际上,您可以进一步简化它,并完全删除
元素。我已经更新了我的答案。是的,做得很好。我假设第一个$(this).contents().filter
是使函数递归还是什么?棒极了。