From a question asked over here about replacing ordinary text within a string into a URL.... I want to make it work if the link text is surrounded by <br/>
tags.
从这里提出的关于将字符串中的普通文本替换为URL的问题....如果链接文本被
标签包围,我想使它工作。
This is the code I am using so far which does 'linkify' text within an element that appears to be a hyperlink:
这是我到目前为止使用的代码,它在一个看似超链接的元素中“链接”文本:
function linkify(inputText) {
var replacedText, replacePattern1, replacePattern2, replacePattern3;
//URLs starting with http://, https://, or ftp://
replacePattern1 = /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim;
replacedText = inputText.replace(replacePattern1, '<a href="$1" target="_blank">$1</a>');
//URLs starting with "www." (without // before it, or it'd re-link the ones done above).
replacePattern2 = /(^|[^\/])(www\.[\S]+(\b|$))/gim;
replacedText = replacedText.replace(replacePattern2, '$1<a href="http://$2" target="_blank">$2</a>');
return replacedText;
}
Of course the problem is that if the link text is like this:
当然问题是,如果链接文本是这样的:
<p>Is this:<br/><br/>http://www.google.com<br/><br/>THE best search engine around?</p>
这是:
http://www.google.com
最好的搜索引擎?
Then the output I get ends up being this!
然后输出我得到了这个!
<p>Is this:<a href="http://www.google.com">http://www.google.comTHE</a> best search engine around</p>
这是: http://www.google.comTHE 最佳搜索引擎
So two problems are that the <br/>
tags are getting stripped out completely and also that the text after the <br/>
tag ('THIS') is being treated as part of the hyperlink text.
因此,两个问题是,标签被完全剥离,并且标签('THIS')之后的文本被视为超链接文本的一部分。
How could I overcome this small but deadly issue?
我怎么能克服这个小而致命的问题呢?
2 个解决方案
#1
3
I would rely a lot more on the browsers built in parsing abilities, and let the browser figure out what's valid HTML etc.
我会更多地依赖于解析功能中构建的浏览器,并让浏览器找出有效的HTML等。
Something like this should work
这样的事情应该有效
function linkify(inputText) {
var dom = new DOMParser(),
doc = dom.parseFromString('<div id="wrap">'+ inputText +'</div>', 'text/html'),
ref = doc.getElementById('wrap'),
reg = /[-a-zA-Z0-9@:%_\+.~#?&//=]{2,256}\.[a-z]{2,4}\b(\/[-a-zA-Z0-9@:%_\+.~#?&//=]*)?/gi,
arr = [];
Array.prototype.forEach.call(ref.querySelectorAll('*'), function(node) {
Array.prototype.forEach.call(node.childNodes, function(innerNode) {
if (innerNode.nodeType === 3) arr.push(innerNode);
});
});
arr.forEach(function(node, index) {
node.nodeValue = node.nodeValue.replace(reg, function(x) {
var nxtNode = arr[index+1],
anchor = doc.createElement('a');
if (nxtNode && "nodeValue" in nxtNode) {
anchor.href = x;
anchor.innerHTML = nxtNode.nodeValue;
nxtNode.parentNode.removeChild(nxtNode);
node.parentNode.insertBefore(anchor, node);
node.parentNode.removeChild(node);
}
});
});
return ref.innerHTML;
}
would return
会回来的
<p>
<br><br>
<a href="http://www.google.com">THE best search engine around</a>
<br><br>
</p>`
keeping all the breaks, but placing them outside the anchor
保持所有休息时间,但将它们放在锚点之外
小提琴
#2
1
I propose to add another replacement in your function in order to execute your strip:
我建议在你的函数中添加另一个替换来执行你的strip:
function linkify(inputText) {
var replacedText, replacePattern1, replacePattern2, replacePattern3;
//URLs starting with http://, https://, or ftp://
replacePattern1 = /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim;
replacedText = inputText.replace(/<br\/>/gi, '').replace(replacePattern1, '<a href="$1" target="_blank">$1</a>');
//URLs starting with "www." (without // before it, or it'd re-link the ones done above).
replacePattern2 = /(^|[^\/])(www\.[\S]+(\b|$))/gim;
replacedText = replacedText.replace(replacePattern2, '$1<a href="http://$2" target="_blank">$2</a>');
return replacedText;
}
#1
3
I would rely a lot more on the browsers built in parsing abilities, and let the browser figure out what's valid HTML etc.
我会更多地依赖于解析功能中构建的浏览器,并让浏览器找出有效的HTML等。
Something like this should work
这样的事情应该有效
function linkify(inputText) {
var dom = new DOMParser(),
doc = dom.parseFromString('<div id="wrap">'+ inputText +'</div>', 'text/html'),
ref = doc.getElementById('wrap'),
reg = /[-a-zA-Z0-9@:%_\+.~#?&//=]{2,256}\.[a-z]{2,4}\b(\/[-a-zA-Z0-9@:%_\+.~#?&//=]*)?/gi,
arr = [];
Array.prototype.forEach.call(ref.querySelectorAll('*'), function(node) {
Array.prototype.forEach.call(node.childNodes, function(innerNode) {
if (innerNode.nodeType === 3) arr.push(innerNode);
});
});
arr.forEach(function(node, index) {
node.nodeValue = node.nodeValue.replace(reg, function(x) {
var nxtNode = arr[index+1],
anchor = doc.createElement('a');
if (nxtNode && "nodeValue" in nxtNode) {
anchor.href = x;
anchor.innerHTML = nxtNode.nodeValue;
nxtNode.parentNode.removeChild(nxtNode);
node.parentNode.insertBefore(anchor, node);
node.parentNode.removeChild(node);
}
});
});
return ref.innerHTML;
}
would return
会回来的
<p>
<br><br>
<a href="http://www.google.com">THE best search engine around</a>
<br><br>
</p>`
keeping all the breaks, but placing them outside the anchor
保持所有休息时间,但将它们放在锚点之外
小提琴
#2
1
I propose to add another replacement in your function in order to execute your strip:
我建议在你的函数中添加另一个替换来执行你的strip:
function linkify(inputText) {
var replacedText, replacePattern1, replacePattern2, replacePattern3;
//URLs starting with http://, https://, or ftp://
replacePattern1 = /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim;
replacedText = inputText.replace(/<br\/>/gi, '').replace(replacePattern1, '<a href="$1" target="_blank">$1</a>');
//URLs starting with "www." (without // before it, or it'd re-link the ones done above).
replacePattern2 = /(^|[^\/])(www\.[\S]+(\b|$))/gim;
replacedText = replacedText.replace(replacePattern2, '$1<a href="http://$2" target="_blank">$2</a>');
return replacedText;
}