簡體   English   中英

將HTML中的鏈接轉換為錨點

[英]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, '&quot;'),
            '">');
        addText(text);
        html.push('</a>');
    }
};

您可以借用showdown.js正則表達式來解析鏈接。 它將解析純文本並忽略HTML。

\b(((https?|ftp|dict):\/\/|www\.)[^'">\s]+\.[^'">\s]+)(?=\s|$)(?!["<>])

regex101.com測試

請記住,在以下情況(格式奇怪的html)中,它會解析不足:

  • <a href="www.google.com ">bla</a>
  • <a href="www.google.com\\n">bla</a> (\\ n是換行符)

這是一個棘手的問題,因為文本linkAnchor標記同時存在。 我試圖解決這個問題。 請看下面的代碼。 您也可以在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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM