source

플레인 URL을 링크로 대체하려면 어떻게 해야 합니까?

gigabyte 2023. 1. 22. 22:28
반응형

플레인 URL을 링크로 대체하려면 어떻게 해야 합니까?

아래 함수를 사용하여 주어진 텍스트 내의 URL을 대조하여 HTML 링크로 대체하고 있습니다.정규 표현은 훌륭하지만, 현재는 첫 번째 경기만 교체하고 있습니다.

모든 URL을 대체하려면 어떻게 해야 하나요?exec 명령어를 사용해야 할 것 같습니다만, 어떻게 해야 할지 잘 몰랐습니다.

function replaceURLWithHTMLLinks(text) {
    var exp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/i;
    return text.replace(exp,"<a href='$1'>$1</a>"); 
}

우선 자신의 regexp를 롤링하여 URL을 해석하는 것은 좋지 않습니다.RFC에 따르면 이는 다른 사용자가 라이브러리를 작성, 디버깅 및 테스트했을 정도로 일반적인 문제라고 생각할 필요가 있습니다.URI는 복잡합니다.Node.js의 URL 해석 코드URI 스킴의 Wikipedia 페이지를 확인하십시오.

URL 의 해석에는, 많은 엣지 케이스가 있습니다.국제 도메인명, 실제(.museum하지 않음('').etc) TLD, 괄호를 포함한 이상한 구두점, URL 말미의 구두점, IPV6 호스트명 등.

저는 많은 도서관살펴봤지만 몇 가지 단점이 있긴 하지만 사용할 가치가 있는 도서관이 몇 가지 있습니다.

이 작업에 대해 신속하게 자격을 박탈한 라이브러리:

정규 표현을 고집하는 경우 가장 포괄적인 것은 컴포넌트로부터의 URL regexp입니다.단, 존재하지 않는2글자의 TLD를 확인함으로써 잘못 검출됩니다.

URL을 링크로 대체(일반 문제에 대한 답변)

질문의 정규 표현에는 많은 에지 케이스가 누락되어 있습니다.URL을 검출할 때는, 국제 도메인명을 취급하는 전용 라이브러리를 사용하는 것이 좋습니다.새로운 TLD는 다음과 같습니다..museum, 괄호 및 URL의 마지막 구두점 및 기타 많은 엣지 케이스.기타 문제에 대한 설명은 Jeff Atwood의 블로그 투고 The Problem With URLs를 참조하십시오.

URL 매칭 라이브러리의 가장 좋은 요약은 Dan Dascalescu의 답변에 있습니다.
)(2014년 2월 기준)


"정규 표현으로 두 개 이상의 일치를 바꿉니다." (특정 문제에 대한 답변)

글로벌 매칭을 활성화하려면 정규 표현 끝에 "g"를 추가합니다.

/ig;

그러나 이는 정규 표현이 첫 번째 일치만 대체한 문제의 문제만 해결합니다.그 코드를 사용하지 마세요.

Travis의 코드에 약간의 수정을 가했습니다(불필요한 재명령을 피하기 위해서입니다만, 제 요구에 잘 대응하고 있습니다.잘했습니다).

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>');

    //Change email addresses to mailto:: links.
    replacePattern3 = /(([a-zA-Z0-9\-\_\.])+@[a-zA-Z\_]+?(\.[a-zA-Z]{2,6})+)/gim;
    replacedText = replacedText.replace(replacePattern3, '<a href="mailto:$1">$1</a>');

    return replacedText;
}

Travis's Travis's에 대한 작업을 했습니다.Linkify(), 서브 example@domain.co.uk했습니다.또, 서브 도메인 타입의 형식의 전자 메일 주소가 일치하지 않는 버그(example@domain.co.uk 등)도 수정했습니다.

이 .String다음과 같이 항목을 일치시킬 수 있습니다.

var text = 'address@example.com';
text.linkify();

'http://stackoverflow.com/'.linkify();

어쨌든, 대본은 다음과 같습니다.

if(!String.linkify) {
    String.prototype.linkify = function() {

        // http://, https://, ftp://
        var urlPattern = /\b(?:https?|ftp):\/\/[a-z0-9-+&@#\/%?=~_|!:,.;]*[a-z0-9-+&@#\/%=~_|]/gim;

        // www. sans http:// or https://
        var pseudoUrlPattern = /(^|[^\/])(www\.[\S]+(\b|$))/gim;

        // Email addresses
        var 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>');
    };
}

감사합니다, 정말 도움이 되었습니다.저는 URL처럼 보이는 것을 링크하는 것도 원했습니다.기본 요건으로 http:// protocol prefix가 없어도 www.yahoo.com과 같은 것을 링크할 수 있습니다.따라서 기본적으로 "www."가 있으면 링크되어 http://로 간주됩니다.메일도 mailto: 링크로 변환하고 싶었습니다.예: www.yahoo.com은 www.yahoo.com으로 변환됩니다.

이 페이지의 코드와 온라인에서 찾은 다른 것, 그리고 내가 직접 한 다른 것들의 조합은 다음과 같습니다.

function Linkify(inputText) {
    //URLs starting with http://, https://, or ftp://
    var replacePattern1 = /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim;
    var 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)
    var replacePattern2 = /(^|[^\/])(www\.[\S]+(\b|$))/gim;
    var replacedText = replacedText.replace(replacePattern2, '$1<a href="http://$2" target="_blank">$2</a>');

    //Change email addresses to mailto:: links
    var replacePattern3 = /(\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,6})/gim;
    var replacedText = replacedText.replace(replacePattern3, '<a href="mailto:$1">$1</a>');

    return replacedText
}

두 번째 치환에서 (^|[^/]) 부분은 첫 번째 치환에서 URL이 이미 링크되어 있는 경우 이중으로 변환되지 않도록 하기 위해 접두사가 아직 //로 지정되지 않은 경우에만 www.whatever.com을 대체합니다.또한 정규식의 첫 번째 "or" 조건인 문자열의 선두에 www.whatever.com이 있을 수 있습니다.

위의 Jesse P와 같이 jQuery 플러그인으로 통합할 수 있지만, 저는 특별히 기존의 DOM 요소에서 동작하지 않는 일반 함수를 원했습니다. 왜냐하면 제가 가지고 있는 텍스트를 DOM에 추가하기 전에 "링크"하고 싶기 때문입니다.그래서 이 함수를 통해 텍스트를 전달합니다.효과가 좋다.

있는 가 많고 하지 않는 가 많기 하기 위한 하지만 URL과 함께 하는 기능을 수 . URL을 하이퍼링크로 대체하기 위한 자바스크립트 함수는 많이 존재하지만, 저는 URL과 마찬가지로 작동하는 함수를 찾을 수 없었습니다.urlize파이썬 장고 나는 의 江'를 포팅했다.urlizeJavaScript : :

https://github.com/ljosa/urlize.js

예:

urlize('Go to SO (stackoverflow.com) and ask. <grin>', 
       {nofollow: true, autoescape: true})
=> "Go to SO (<a href="http://stackoverflow.com" rel="nofollow">stackoverflow.com</a>) and ask. &lt;grin&gt;"

인수는 " " " ( " " " )를 발생시킵니다.rel="nofollow"삽입할 수 있습니다.세 번째 인수(true인 경우)는 HTML에서 특별한 의미가 있는 문자를 이스케이프합니다.README 파일을 참조하십시오.

구글에서 더 새로운 것을 검색해봤더니 이런 것을 발견했어요.

$('p').each(function(){
   $(this).html( $(this).html().replace(/((http|https|ftp):\/\/[\w?=&.\/-;#~%-]+(?![\w\s?&.\/;#~%"=-]*>))/g, '<a href="$1">$1</a> ') );
});

데모: http://jsfiddle.net/kachibito/hEgvc/1/

일반 링크에서 매우 잘 작동합니다.

aaa.bb를 인식하기 위해 Roshambo String.linkify()를 emailAddressPattern으로 변경하였습니다.@cc.ddd 주소

if(!String.linkify) {
    String.prototype.linkify = function() {

        // http://, https://, ftp://
        var urlPattern = /\b(?:https?|ftp):\/\/[a-z0-9-+&@#\/%?=~_|!:,.;]*[a-z0-9-+&@#\/%=~_|]/gim;

        // www. sans http:// or https://
        var pseudoUrlPattern = /(^|[^\/])(www\.[\S]+(\b|$))/gim;

        // Email addresses *** here I've changed the expression ***
        var emailAddressPattern = /(([a-zA-Z0-9_\-\.]+)@[a-zA-Z_]+?(?:\.[a-zA-Z]{2,6}))+/gim;

        return this
            .replace(urlPattern, '<a target="_blank" href="$&">$&</a>')
            .replace(pseudoUrlPattern, '$1<a target="_blank" href="http://$2">$2</a>')
            .replace(emailAddressPattern, '<a target="_blank" href="mailto:$1">$1</a>');
    };
}
/**
 * Convert URLs in a string to anchor buttons
 * @param {!string} string
 * @returns {!string}
 */

function URLify(string){
  var urls = string.match(/(((ftp|https?):\/\/)[\-\w@:%_\+.~#?,&\/\/=]+)/g);
  if (urls) {
    urls.forEach(function (url) {
      string = string.replace(url, '<a target="_blank" href="' + url + '">' + url + "</a>");
    });
  }
  return string.replace("(", "<br/>(");
}

간단한 예

이를 위한 최적의 스크립트:http://benalman.com/projects/javascript-linkify-process-lin/

이 솔루션은 다른 솔루션과 마찬가지로 동작하며, 실제로는 그 중 하나와 동일한 regex를 사용하지만 HTML String을 반환하는 대신 A 요소와 적용 가능한 텍스트노드를 포함하는 문서 fragment를 반환합니다.

 function make_link(string) {
    var words = string.split(' '),
        ret = document.createDocumentFragment();
    for (var i = 0, l = words.length; i < l; i++) {
        if (words[i].match(/[-a-zA-Z0-9@:%_\+.~#?&//=]{2,256}\.[a-z]{2,4}\b(\/[-a-zA-Z0-9@:%_\+.~#?&//=]*)?/gi)) {
            var elm = document.createElement('a');
            elm.href = words[i];
            elm.textContent = words[i];
            if (ret.childNodes.length > 0) {
                ret.lastChild.textContent += ' ';
            }
            ret.appendChild(elm);
        } else {
            if (ret.lastChild && ret.lastChild.nodeType === 3) {
                ret.lastChild.textContent += ' ' + words[i];
            } else {
                ret.appendChild(document.createTextNode(' ' + words[i]));
            }
        }
    }
    return ret;
}

오래된 IE 및 textContent 지원 등 몇 가지 주의사항이 있습니다.

여기 데모가 있습니다.

더 짧은 링크(도메인만)를 표시해야 하지만 URL이 긴 경우 위에 게시된 Sam Hasler의 코드 버전을 수정해 보십시오.

function replaceURLWithHTMLLinks(text) {
    var exp = /(\b(https?|ftp|file):\/\/([-A-Z0-9+&@#%?=~_|!:,.;]*)([-A-Z0-9+&@#%?\/=~_|!:,.;]*)[-A-Z0-9+&@#\/%=~_|])/ig;
    return text.replace(exp, "<a href='$1' target='_blank'>$3</a>");
}

등록 예: /(\b((https?|ftp|file):\/\/|(www))[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|]*)/ig

function UriphiMe(text) {
      var exp = /(\b((https?|ftp|file):\/\/|(www))[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|]*)/ig; 
      return text.replace(exp,"<a href='$1'>$1</a>");
}

테스트된 문자열은 다음과 같습니다.

  1. www.google.com에 접속해 주세요.
  2. 월드와이드웹
  3. www.http://www.com에 접속해 주세요.
  4. 팔로우:http://www.nishantwork.wordpress.com
  5. http://www.nishantwork.wordpress.com
  6. 팔로우:http://www.nishantwork.wordpress.com
  7. https://stackoverflow.com/users/430803/nishant

합격하고 않은 : 합격하고 싶지 않은 경우:www다음 reg ex를 사용하면 유효합니다./(\b((https?|ftp|file):\/\/|(www))[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig

URI의 복잡성에 대한 경고는 주의할 필요가 있지만 질문에 대한 간단한 답변은 다음과 같습니다.
하는 항목을 " " 를 ./gRegEx의 를 붙입니다.
/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gi

심플하게!가질 수 있는 것이 아니라 가질 수 없는 것을 말하세요:)

한 바와 같이 뒤에 할 수 , 하는 것은 를 들어 'www'로 시작하는 것은 아닙니다.maps.bing.com/something?key=!"£$%^*()&lat=65&lon&lon=20

따라서 모든 엣지 케이스에 대응할 수 없고 유지보수가 어려운 복잡한 regex보다는 훨씬 단순한 regex를 사용하는 것이 좋습니다.실천에서는 이 방법이 효과적입니다.

경기

http(s):// (anything but a space)+

www. (anything but a space)+

'anything'은 'anything'입니다.[^'"<>\s]으로는 공간,괄호 의 끝과 입니다. 기본적으로는 공간, 따옴표, 꺾쇠 괄호 또는 줄 끝과 일치하는 탐욕스러운 일치입니다.

기타:

을 확인해 를 들어, 에는 「」의 URL이 포함되어 있습니다.href="..." ★★★★★★★★★★★★★★★★★」src="..."

ref=nofollow 추가(해당하는 경우)

이 솔루션은 위에서 설명한 라이브러리만큼 "좋은" 솔루션은 아니지만 훨씬 단순하고 실제로도 잘 작동합니다.

if html.match( /(href)|(src)/i )) {
    return html; // text already has a hyper link in it
    }

html = html.replace( 
            /\b(https?:\/\/[^\s\(\)\'\"\<\>]+)/ig, 
            "<a ref='nofollow' href='$1'>$1</a>" 
            );

html = html.replace( 
            /\s(www\.[^\s\(\)\'\"\<\>]+)/ig, 
            "<a ref='nofollow' href='http://$1'>$1</a>" 
            );

html = html.replace( 
             /^(www\.[^\s\(\)\'\"\<\>]+)/ig, 
            "<a ref='nofollow' href='http://$1'>$1</a>" 
            );

return html;

국제 도메인과 아스트랄 문자를 지원하는 올바른 URL 검출은 간단한 일이 아닙니다. linkify-it라이브러리는 많은 상황에서 regex를 빌드하고 최종 사이즈는 약 6킬로바이트입니다.이것은 현재 받아들여진 답변에서 참조되고 있는 모든 libs보다 정확합니다.

라이브의 모든 엣지 케이스를 확인하고 테스트하려면 linkify-it 데모를 참조하십시오.

HTML 소스를 연결해야 할 경우 먼저 해석하고 각 텍스트 토큰을 개별적으로 반복해야 합니다.

다음의 기능을 시험해 보겠습니다.

function anchorify(text){
  var exp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;
  var text1=text.replace(exp, "<a href='$1'>$1</a>");
  var exp2 =/(^|[^\/])(www\.[\S]+(\b|$))/gim;
  return text1.replace(exp2, '$1<a target="_blank" href="http://$2">$2</a>');
}

alert(anchorify("Hola amigo! https://www.sharda.ac.in/academics/"));

또 다른 JavaScript 라이브러리를 작성했습니다.빠르고 작은 사이즈로 가능한 최소한의 잘못된 긍정으로 매우 민감하기 때문에 당신에게 더 좋을지도 모릅니다.현재 적극적으로 보수하고 있으므로 데모 페이지에서 테스트하여 어떻게 동작하는지 확인해 주십시오.

링크: https://github.com/alexcorvi/anchorme.js

반대로 html 링크를 URL로만 만들어야 했는데, 당신의 regex를 수정해서 정말 잘 작동합니다.감사합니다.

var exp = /<a\s.*href=[']" (\b(filename?|filename|파일):\/\/[-A-Z0-9+&@#\/%?=~_|:, branto]*[-A-Z0-9+&@#\/%=~_|])[']*>*<\/a>/ig;
소스 = source.replace(exp,"$1");

위의 Travitron의 답변에 기재된 이메일 검출이 기능하지 않아 아래와 같이 확장/교환하였습니다(C#코드).

// Change e-mail addresses to mailto: links.
const RegexOptions o = RegexOptions.Multiline | RegexOptions.IgnoreCase;
const string pat3 = @"([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,6})";
const string rep3 = @"<a href=""mailto:$1@$2.$3"">$1@$2.$3</a>";
text = Regex.Replace(text, pat3, rep3, o);

이를 통해 "first name"과 같은 전자 메일 주소를 사용할 수 있습니다.secondname@one.two.three.co.uk"을 참조해 주세요.

몇 가지 소스로부터 입력을 받은 결과, 저는 이제 제대로 작동하는 솔루션이 되었습니다.그건 당신만의 대체 코드를 쓰는 것과 관련이 있어요.

대답하다.

만지작거리다.

function replaceURLWithHTMLLinks(text) {
    var re = /(\(.*?)?\b((?:https?|ftp|file):\/\/[-a-z0-9+&@#\/%?=~_()|!:,.;]*[-a-z0-9+&@#\/%=~_()|])/ig;
    return text.replace(re, function(match, lParens, url) {
        var rParens = '';
        lParens = lParens || '';

        // Try to strip the same number of right parens from url
        // as there are left parens.  Here, lParenCounter must be
        // a RegExp object.  You cannot use a literal
        //     while (/\(/g.exec(lParens)) { ... }
        // because an object is needed to store the lastIndex state.
        var lParenCounter = /\(/g;
        while (lParenCounter.exec(lParens)) {
            var m;
            // We want m[1] to be greedy, unless a period precedes the
            // right parenthesis.  These tests cannot be simplified as
            //     /(.*)(\.?\).*)/.exec(url)
            // because if (.*) is greedy then \.? never gets a chance.
            if (m = /(.*)(\.\).*)/.exec(url) ||
                    /(.*)(\).*)/.exec(url)) {
                url = m[1];
                rParens = m[2] + rParens;
            }
        }
        return lParens + "<a href='" + url + "'>" + url + "</a>" + rParens;
    });
}

제 해결책은 다음과 같습니다.

var content = "Visit https://wwww.google.com or watch this video: https://www.youtube.com/watch?v=0T4DQYgsazo and news at http://www.bbc.com";
content = replaceUrlsWithLinks(content, "http://");
content = replaceUrlsWithLinks(content, "https://");

function replaceUrlsWithLinks(content, protocol) {
    var startPos = 0;
    var s = 0;

    while (s < content.length) {
        startPos = content.indexOf(protocol, s);

        if (startPos < 0)
            return content;

        let endPos = content.indexOf(" ", startPos + 1);

        if (endPos < 0)
            endPos = content.length;

        let url = content.substr(startPos, endPos - startPos);

        if (url.endsWith(".") || url.endsWith("?") || url.endsWith(",")) {
            url = url.substr(0, url.length - 1);
            endPos--;
        }

        if (ROOTNS.utils.stringsHelper.validUrl(url)) {
            let link = "<a href='" + url + "'>" + url + "</a>";
            content = content.substr(0, startPos) + link + content.substr(endPos);
            s = startPos + link.length;
        } else {
            s = endPos + 1;
        }
    }

    return content;
}

function validUrl(url) {
    try {
        new URL(url);
        return true;
    } catch (e) {
        return false;
    }
}

아래 솔루션 시험

function replaceLinkClickableLink(url = '') {
let pattern = new RegExp('^(https?:\\/\\/)?'+
        '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.?)+[a-z]{2,}|'+
        '((\\d{1,3}\\.){3}\\d{1,3}))'+
        '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+
        '(\\?[;&a-z\\d%_.~+=-]*)?'+
        '(\\#[-a-z\\d_]*)?$','i');

let isUrl = pattern.test(url);
if (isUrl) {
    return `<a href="${url}" target="_blank">${url}</a>`;
}
return url;
}

텍스트 내의 URL을 HTML 링크로 대체하고 href/pre 태그 내의 URL을 무시합니다.https://github.com/JimLiu/auto-link

나를 위해 일했어:

var urlRegex =/(\b((https?|ftp|file):\/\/)?((([a-z\d]([a-z\d-]*[a-z\d])*)\.)+[a-z]{2,}|((\d{1,3}\.){3}\d{1,3}))(\:\d+)?(\/[-a-z\d%_.~+]*)*(\?[;&a-z\d%_.~+=-]*)?(\#[-a-z\d_]*)?)/ig;

return text.replace(urlRegex, function(url) {
    var newUrl = url.indexOf("http") === -1 ? "http://" + url : url;
    return '<a href="' + newUrl + '">' + url + '</a>';
});

언급URL : https://stackoverflow.com/questions/37684/how-to-replace-plain-urls-with-links

반응형