[英]Convert links in HTML to anchors
我有一個HTML文本,需要用錨替換鏈接(例如www.so.com)。
輸入為:
<p>Hi I have a nice website on www.so.com and would...</p>
<p>Click <a href='http://www.so.com'>this link</a></p>
輸出應返回:
<p>Hi I have a nice website on <a href='www.so.com'>www.so.com</a> and would...</p>
<p>Click <a href='http://www.so.com'>this link</a></p>
棘手的部分是HTML文本中已有的錨點。
我正在努力解決迄今為止的解決方案。 過濾器第一次用錨替換鏈接,但是第二次...
.filter('autolink', ['$sanitize', function ($sanitize) {
var LINKY_URL_REGEXP =
/((ftp|https?):\/\/|(www\.)|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>"\u201d\u2019]/i,
MAILTO_REGEXP = /^mailto:/i;
return function (text, target, attributes) {
if (!text) return text;
var match;
var raw = text;
var html = [];
var url;
var i;
while ((match = raw.match(LINKY_URL_REGEXP))) {
// We can not end in these as they are sometimes found at the end of the sentence
url = match[0];
// if we did not match ftp/http/www/mailto then assume mailto
if (!match[2] && !match[4]) {
url = (match[3] ? 'http://' : 'mailto:') + url;
}
i = match.index;
addText(raw.substr(0, i));
addLink(url, match[0].replace(MAILTO_REGEXP, ''));
raw = raw.substring(i + match[0].length);
}
addText(raw);
return html.join('');
function addText(text) {
if (!text) {
return;
}
html.push(text);
}
function addLink(url, text) {
var key;
html.push('<a ');
if (angular.isFunction(attributes)) {
attributes = attributes(url);
}
if (angular.isObject(attributes)) {
for (key in attributes) {
html.push(key + '="' + attributes[key] + '" ');
}
} else {
attributes = {};
}
if (angular.isDefined(target) && !('target' in attributes)) {
html.push('target="',
target,
'" ');
}
html.push('href="',
url.replace(/"/g, '"'),
'">');
addText(text);
html.push('</a>');
}
};
您可以借用showdown.js正則表達式來解析鏈接。 它將解析純文本並忽略HTML。
\b(((https?|ftp|dict):\/\/|www\.)[^'">\s]+\.[^'">\s]+)(?=\s|$)(?!["<>])
請記住,在以下情況(格式奇怪的html)中,它會解析不足:
<a href="www.google.com ">bla</a>
<a href="www.google.com\\n">bla</a>
(\\ n是換行符) 這是一個棘手的問題,因為文本link
和Anchor
標記同時存在。 我試圖解決這個問題。 請看下面的代碼。 您也可以在Codepen上查看相同內容 。
輸入字符串( var plainText
)
<p>Hola! This is my sincere attempt on www.stackoverflow.com to solve this problem.</p><p>Click <a href=\'https://stackoverflow.com/questions/33783154/convert-links-in-html-to-anchors\'>here</a> to view my answer.</p><p>Thanks for your time!</p><p><a href="https://stackoverflow.com/">Stackoverflow rocks!</a></p>
輸出字符串( var updatedTextAnchorify
)
<p>Hola! This is my sincere attempt on <a href="http://www.stackoverflow.com">www.stackoverflow.com</a> to solve this problem.</p><p>Click <a href="https://stackoverflow.com/questions/33783154/convert-links-in-html-to-anchors">here</a> to view my answer.</p><p>Thanks for your time!</p><p><a href="https://stackoverflow.com/">Stackoverflow rocks!</a></p>
代碼段
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<title>Anchorify</title>
</head>
<body>
<script>
(function() {
if (!String.anchorify) {
String.prototype.anchorify = function() {
var
// http://, https://, ftp://
urlPattern = /\b(?:https?|ftp):\/\/[a-z0-9-+&@#\/%?=~_|!:,.;]*[a-z0-9-+&@#\/%=~_|]/gim,
// www., Sans http:// or https://
pseudoUrlPattern = /(^|[^\/])(www\.[\S]+(\b|$))/gim,
// Email addresses
emailAddressPattern = /[\w.]+@[a-zA-Z_-]+?(?:\.[a-zA-Z]{2,6})+/gim;
return this
.replace(urlPattern, '<a href="$&">$&</a>')
.replace(pseudoUrlPattern, '$1<a href="http://$2">$2</a>')
.replace(emailAddressPattern, '<a href="mailto:$&">$&</a>');
};
}
var
// Initial text to be converted/anchorified
// initialText =
plainText = '<p>Hola! This is my sincere attempt on www.stackoverflow.com to solve this problem.</p><p>Click <a href=\'https://stackoverflow.com/questions/33783154/convert-links-in-html-to-anchors\'>here</a> to view my answer.</p><p>Thanks for your time!</p><p><a href="https://stackoverflow.com/">Stackoverflow rocks!</a></p>',
// plainText = initialText.replace(/\r?\n|\r/gim, ''),
matchesObj = {},
anchorTagPattern = /(<a href=(?:'|")([^"]+)(?:'|")>([^<]+)<\/a>)/gim,
updatedText = plainText.replace(anchorTagPattern, function () {
var slice = Array.prototype.slice.call(arguments, 1, 4);
matchesObj[slice[1]] = '<a href="' + slice[1] + '">' + slice[2] + '</a>';
return slice[1];
}),
updatedTextAnchorify = updatedText.anchorify();
// Iterate
for (var property in matchesObj) {
if (matchesObj.hasOwnProperty(property)) {
var replaceStr = '<a href="' + property + '">' + property + '</a>';
updatedTextAnchorify = updatedTextAnchorify.replace(replaceStr, matchesObj[property])
}
}
// Write to the Document
document.write(updatedTextAnchorify);
})();
</script>
</body>
</html>
另外,請查看此Stackoverflow答案,該答案清楚地說明了為什么滾動自己的正則表達式來解析URL是一個糟糕的主意,並提供了一些有用的參考。
要測試您自己的輸入字符串,只需更改var plainText
。
我希望這有幫助!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.