일반 URL을 링크로 바꾸는 방법?


453

주어진 텍스트 내에서 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>"); 
}

답변:


350

첫째, URL을 구문 분석하기 위해 자신의 정규 표현식을 굴리는 것은 끔찍한 아이디어 입니다. RFC 에 따르면 누군가가 라이브러리를 작성, 디버깅 및 테스트 했을 때 발생하는 일반적인 문제라고 생각해야합니다 . URI는 복잡 - 아웃 확인 Node.js를에서 URL 파싱 코드 와의 위키 백과 페이지 URI 체계를 .

국제 도메인 이름 , 실제 ( .museum) vs 존재하지 않는 ( .etc) TLD, 괄호를 포함한 이상한 구두점 , URL 끝에 구두점, IPV6 호스트 이름 등 URL 을 구문 분석 할 때 매우 다양한 경우가 있습니다 .

내가 검토 한 라이브러리 , 일부 단점에도 불구하고 사용하는 몇 가지 가치가있다 :

이 작업을 위해 신속하게 실격 된 라이브러리 :

정규식을 고집하면 ComponentURL 정규 표현식 이 가장 포괄적 이지만, 존재하지 않는 2 문자 TLD를 살펴보면 잘못 감지합니다.


3
그것은 URL regexp from Component언급되지 않은 것이 유감 이며, 그것이하고있는 일에 대한 설명이 도움이 될 것입니다. Autolinker.js매우 잘 주석을 달았으며 테스트를 거쳤습니다. Vebjorn Ljosa의 답변urlize.js 에 링크 된 라이브러리 는 테스트가 없지만 기능적이고 잘 유지됩니다.
Sam Hasler

1
Regex101.com은 자동으로 정규 표현식을 "설명" 하지만 행운을 빕니다 :) 잘못된 TLD (동일한 링크)로 실패 사례를 빨리 발견했습니다.
Dan Dascalescu

1
@ SamHasler : 자동 링커는 TLD 및 IDN 영역에서 개선해야합니다. 몇 가지 테스트를 추가했습니다 .
Dan Dascalescu

2
URL 정규식 패턴 을 유지하려는 John Gruber의 노력에 대해 언급 한 사람이 아무도 없습니다 . 문제에 대한 유일한 / 이상적인 해결책은 아니지만, 자신의 솔루션을 롤링하는 경우 조사 할 가치가 있습니다. 이것을 참조로 추가하고 싶었습니다.
oelna

2
@DanDascalescu이 markdown-it.github.io/linkify-it를 살펴보십시오 . 이 라이브러리는 텍스트에서 링크 패턴을 감지하여 정확히 하나의 작업에 중점을 둡니다. 그러나 나는 그것을 잘한다. 예를 들어, 아스트랄 문자를 포함하여 올바른 유니 코드 지원이 있습니다. 그리고 국제 TLD를 지원합니다.
Vitaly

285

URL을 링크로 바꾸기 (일반적인 문제에 대한 답변)

질문의 정규 표현식은 많은 경우를 놓칩니다. URL을 감지 할 때는 항상 국제 도메인 이름,와 같은 새로운 TLD .museum, 괄호 및 URL 내부 및 끝에있는 구두점 및 기타 여러 가지 경우 를 처리하는 특수 라이브러리를 사용하는 것이 좋습니다 . 다른 문제에 대한 설명은 Jeff Atwood의 블로그 게시물 URL 관련 문제를 참조하십시오.

URL 매칭 라이브러리의 가장 요약댄 Dascalescu의 대답+100
(2014 2월 현재)


"정규식으로 두 개 이상의 일치 항목을 교체하십시오"(특정 문제에 대한 답변)

전역 표현식을 활성화하려면 정규 표현식 끝에 "g"를 추가하십시오.

/ig;

그러나 정규 표현식이 첫 번째 일치 항목 만 바꾸는 문제의 문제 만 수정합니다. 해당 코드를 사용하지 마십시오.


150

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;
}

1
포함 된 객체 및 iframe을 손상시키지 않도록이 코드를 편집하는 방법 .. (youtube 포함 된 객체 및 iframe)
Pradyut Bhattacharya

5
코드에 이메일 주소와 일치하는 버그가 있습니다. 보다 복잡한 도메인 이름 (예 : email@example.co.uk)을 일치 [a-zA-Z]{2,6}시키려면 행을 따라 (?:[a-zA-Z]{2,6})+내용을 읽어야합니다.
Roshambo

1
나는 몇 가지 문제에 부딪쳤다; 먼저 http : // 또는 http : // www 만 있으면 공간 이 없어도 www가 공백으로 잘못 구문 분석하여 링크를 만듭니다. 그리고 http : // www와 링크합니다. 도메인 . 공백없이 com은 하나의 빈 링크를 만들고 href 필드에 앵커 닫기 태그가 첨부 된 하나를 만듭니다.
Alfred

1
http://또는 없는 URL은 www어떻습니까? 이런 종류의 URL에서 작동합니까?
Nathan

2
mailto 문제를 해결하기 위해 원본 게시물을 편집하려고했지만 편집하려면 6 자 이상을 추가해야합니다. 그러나이 줄을 변경하면 : mailto 문제를 해결하는 replacePattern3 = /(\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,6})/gim;이것으로 replacePattern3 = /(\w+@[a-zA-Z_]+?(\.[a-zA-Z]{2,6})+)/gim;:)
yourdeveloperfriend

70

Linkify()위의 Travis 코드 를 일부 최적화했습니다 . 또한 하위 도메인 유형 형식의 이메일 주소가 일치하지 않는 버그를 수정했습니다 (예 : 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>');
    };
}

내 의견으로는 최고, 프로토 타입 기능이 훨씬 더 깨끗해집니다 :)
MRVDOG

info@some-thing.com some.thing@example.com 등 : 이메일 주소와 함께 작동하지 않는 것 같습니다
마르코 Gagliardi은

@MarcoGagliardi 잘 잡았습니다. 결정된.
Roshambo

1
문자열 "git clone aaaa@bitbucket.org/ooo/bbb-cc-dd.git " 에서는 작동하지 않습니다 . 문자열을 덩어리로 나누고 "git clone <a href="https://<a href="mailto:aaaa@bitbucket.org"> aaaa@bitbucket.org </a> / ooo /와 같은 여러 앵커를 만들었습니다. bbb-cc-dd.git "> https : // <a href="mailto:aaaa@bitbucket.org"> aaaa@bitbucket.org </a> /ooo/bbb-cc-dd.git </a> "
Jebin

1
+와 같은 이메일 사용자 이름에서는 작동하지 않습니다 foo+bar@domain.com. 이메일 패턴 /[\w.+]+@[a-zA-Z_-]+?(?:\.[a-zA-Z]{2,6})+/gim( +첫 번째 괄호 안의 참고)으로 고정 했지만 다른 것이 깨지는지는 모르겠습니다.
dchacke

24

감사합니다. 매우 도움이되었습니다. 또한 URL처럼 보이는 것들을 연결하는 무언가를 원했습니다. 기본 요구 사항은 http : // 프로토콜 접두사가없는 경우에도 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
}

두 번째 교체에서 (^ | [^ /]) 부분은 //가 접두사로 붙지 않은 경우 www.whatever.com 만 //로 대체합니다. 첫 번째 교체에서 URL이 이미 연결된 경우 이중 연결을 피하기위한 것입니다. 또한 www.whatever.com이 문자열의 시작 부분에있을 수 있습니다. 이는 정규 표현식의 해당 부분에서 첫 번째 "조건"입니다.

Jesse P가 위에서 설명한 것처럼 jQuery 플러그인으로 통합 될 수는 있지만 기존 DOM 요소에 대해 작동하지 않는 일반 함수를 원했습니다. 텍스트를 가져 와서 DOM에 추가하기 때문입니다. 텍스트를 추가하기 전에 "연결"되기를 원하므로이 함수를 통해 텍스트를 전달합니다. 잘 작동합니다.


1
일반 "www.domain.com"과 일치하는 두 번째 패턴에 문제가 있습니다. url에 일종의 리퍼러가있는 경우 문제가 발생합니다. & location = http % 3A % 2F % 2Fwww.amazon.com % 2FNeil-Young % 2Fe % 2FB000APYJWA % 3Fqid % 3D1280679945 % 26sr % 3D8-2-ent & tag = tra0c7 -20 & linkCode = ur2 & camp = 1789 & creative = 9325-이 경우 링크가 다시 자동 연결됩니다. 빠른 수정은 "/"를 포함하는 부정 된 목록 뒤에 문자 "f"를 추가하는 것입니다. 따라서 표현은 다음과 같습니다. replacePattern2 = /(^|[^\/f])(www\.[\S]+(\b|$))/gim
Redtopia

위의 코드는 엣지 케이스에 대한 많은 테스트에 실패합니다. URL을 감지 할 때는 특수 라이브러리를 사용하는 것이 좋습니다. 이유는 다음과 같습니다 .
Dan Dascalescu

2
방금 웹 링크 중 일부에 이미 href 링크가있는 문자열에서 실행했습니다. 이 경우 기존 작업 링크를 엉망으로 만드는 데 실패합니다.
AdamJones

17

URL은 구두점으로 둘러싸여 있고 사용자가 URL의 전체 형식을 자주 사용하지 않기 때문에 URL을 식별하기가 까다 롭습니다. URL을 하이퍼 링크로 대체하기위한 많은 JavaScript 함수가 존재하지만 urlizePython 기반 웹 프레임 워크 Django에서 필터 뿐만 아니라 작동하는 함수도 찾을 수 없습니다 . 따라서 Django의 urlize기능을 JavaScript 로 이식했습니다 .

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;"

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


또한 다음과 같은 html 소스와 함께 작동합니다 : www.web.com <a href = "https : // github
.com">

@Paulius : 옵션 django_compatible을 false로 설정하면 해당 사용 사례를 조금 더 잘 처리합니다.
Vebjorn Ljosa

Django urlize는 TLD를 올바르게 지원하지 않습니다 (적어도 GitHub의 JS 포트는 아닙니다). TLD를 올바르게 처리 하는 라이브러리 는 Ben Alman의 JavaScript Linkify 입니다.
Dan Dascalescu

URL이 "http"또는 "www"로 시작하지 않는 경우에도 최상위 도메인이 추가 된 URL 감지를 지원합니다.
Vebjorn Ljosa 2014

10

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

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

위의 코드는 엣지 케이스에 대한 많은 테스트에 실패합니다. URL을 감지 할 때는 특수 라이브러리를 사용하는 것이 좋습니다. 이유는 다음과 같습니다 .
Dan Dascalescu

9

나는 구글에서 새로운 것을 찾아서 이것을 가로 질러 달렸다.

$('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/

일반 링크에 정말 효과적입니다.


"일반 링크"란 무엇입니까? jsfiddle.net/hEgvc/27 데모 데모를 살펴보십시오. 사람들은 덮개를 덮지 않고 쉽게 이해할 수 있습니다. URI는 RFC3986에 따라 쉬운 일이 아니며 "일반 링크"만 다루려면 최소한 다음 정규 표현식을 따르는 것이 좋습니다. ^ (([^ : /? #] +) :)? (// ([ ^ /? #] *))? ([^? #] *) (\? ([^ #] *))? (# (. *))?
Ivan

2
나는 형식 http://example.com/folder/folder/folder/이나 https://example.org/blah그 밖의 어떤 것을 의미했습니다 -일반적인 비 미친 URL 형식은 95-99 %의 유스 케이스와 일치합니다. 나는 이것을 내부 관리 영역에 사용하고 있기 때문에 엣지 케이스 또는 해시 링크를 잡기 위해 멋진 것이 필요하지 않습니다.
퇴화


5

이 솔루션은 다른 많은 솔루션과 동일하게 작동하며 실제로는 그 중 하나와 동일한 정규식을 사용하지만 HTML 문자열을 반환하는 대신 A 요소와 해당 텍스트 노드를 포함하는 문서 조각을 반환합니다.

 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 지원과 같은 몇 가지주의 사항이 있습니다.

여기 데모가 있습니다.


2
@DanDascalescu 담요를 많이 내리는 대신에 당신의 우위 사례를 제공 할 수도 있습니다.
rlemon

해야합니까? URL컴포넌트 정규 표현식을 살펴보십시오 . 그러나 당신이 주장한다면 Ben Alman의 linkify test suite 에 대해 달리십시오 . 나는 urlize 와 같은 실패한 테스트에 기여하기 시작 했지만 곧 심각한 라이브러리 노력에만 가치가 있음을 깨달았습니다. 모든 점에서 위의 내용은 URL을 올바르게 구문 분석하려는 오픈 소스 라이브러리가 아닌 StackOverflow 답변입니다.
Dan Dascalescu

2
가장자리가 있습니다. 훌륭한. 이 답변은 여전히 ​​다른 사람들에게 유용 할 수 있으며 그들을 공감하는 담요는 과도한 것처럼 보입니다. 댓글을 달고 겉으로 드러난 것처럼 보이는 답변 에는 유용한 정보 (답변) 포함되어 있습니다. 모든 사람이 해당 사례에 반대되는 것은 아니며 모든 사람이 도서관을 사용하기를 원하는 것은 아닙니다.
rlemon

바로 그거죠. 정규 표현식의 한계를 이해하지 못하는 사람들은 가장 많이 대답 한 답변에서 첫 번째 정규 표현식을 행복하게 훑어가는 사람들입니다. 도서관을 가장 많이 사용해야하는 사람들입니다.
Dan Dascalescu

1
그러나 귀하가 선호하지 않는 솔루션 정규식으로 모든 답변을 다운 투표하는 것이 정당화되는 방법은 무엇입니까?
rlemon

4

더 짧은 링크 (도메인 만 해당)를 표시해야하지만 동일한 긴 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>");
}

3

정규직 : /(\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. www
  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


위의 코드는 엣지 케이스에 대한 많은 테스트에 실패합니다. URL을 감지 할 때는 항상 특수 라이브러리에 의존하는 것이 좋습니다. 이유는 다음과 같습니다 .
Dan Dascalescu

3

URI의 복잡성에 대한 경고에 주목해야하지만 질문에 대한 간단한 대답은 다음과 같습니다.
모든 일치 항목을 바꾸려면 /gRegEx 끝에 플래그를 추가해야합니다 .
/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gi


3
/**
 * 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/>(");
}

간단한 예


2

간단하게 유지하십시오! 가질 수있는 것보다는 가질 수없는 것을 말하십시오. :)

위에서 언급했듯이 URL은 특히 '?'뒤에 매우 복잡 할 수 있으며 모든 URL이 'www'로 시작되는 것은 아닙니다. 예 :maps.bing.com/something?key=!"£$%^*()&lat=65&lon&lon=20

따라서 모든 복잡한 경우를 충족시키지 못하고 유지하기가 어려운 복잡한 정규 표현식을 사용하는 것보다 훨씬 간단한 방법은 실제로 연습에 도움이됩니다.

시합

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

www. (anything but a space)+

'아무것도'가 [^'"<>\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;

2

국제 도메인 및 아스트랄 문자 지원을 통한 올바른 URL 탐지는 사소한 것이 아닙니다. linkify-it라이브러리는 많은 조건 에서 정규식을 빌드 하며 최종 크기는 약 6 킬로바이트입니다. 현재 허용되는 답변에서 참조되는 모든 라이브러리보다 정확합니다.

linkify-it 데모 를 참조 하여 모든 최신 사례를 확인하고 테스트하십시오.

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



0

나는 반대로해야하고 URL로 HTML 링크를 만들어야했지만 정규 표현식을 수정하면 매력처럼 작동합니다. :)

var exp = /<a\s.*href=['"](\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_ |! :,.;] * [-A-Z0-9 + & @ # \ / % = ~ _ |]) [ ' "]. *>. * <\ / a> / ig;

source = source.replace (exp, "$ 1");

정규식의 요점이 보이지 않습니다. 모든 것을 모든 것으로 교체합니다. 실제로 코드는 아무 것도 수행하지 않습니다.
채드 그랜트

8
사람들이 편집을 마치려면 의견을 기다려야한다고 생각합니다. 죄송합니다.
채드 그랜트

0

위의 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);

" firstname.secondname@one.two.three.co.uk " 와 같은 이메일 주소를 허용합니다 .


위의 코드는 엣지 케이스에 대한 많은 테스트에 실패합니다. URL을 감지 할 때는 항상 특수 라이브러리에 의존하는 것이 좋습니다. 이유는 다음과 같습니다 .
Dan Dascalescu 5

감사합니다, @DanDascalescu 일반적으로, 과도하게 일반화하는 것이 좋습니다.
Uwe Keim

0

여러 출처에서 입력 한 후 이제는 잘 작동하는 솔루션을 찾았습니다. 자체 교체 코드 작성과 관련이 있습니다.

대답 .

바이올린 .

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

2
위의 코드 (및 대부분의 정규 표현식)는 엣지 케이스에 대한 많은 테스트에 실패합니다. URL을 감지 할 때는 특수 라이브러리를 사용하는 것이 좋습니다. 이유는 다음과 같습니다 .
Dan Dascalescu

댄, 그런 도서관 있어요? 이 경우 우리는 여전히 위의 정규 표현식과 일치하여 다른 라이브러리가 가비지를 유효한 URL / URI로 인증하더라도) 가비지가 출력되지 않도록 코드가 절대 가비지를 출력하지 않도록합니다.
Mike Mestnik


0

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

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;
    }
}

0

아래 기능을 사용해보십시오 :

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/"));


0

아래 솔루션을 사용해보십시오

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;
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.