JavaScript를 사용하여 텍스트에서 URL 감지


151

누구든지 문자열 집합에서 URL을 감지하기위한 제안이 있습니까?

arrayOfStrings.forEach(function(string){
  // detect URLs in strings and do something swell,
  // like creating elements with links.
});

업데이트 : 링크 감지를 위해이 정규식을 사용하여 마무리했습니다 ... 분명히 몇 년 후에.

kLINK_DETECTION_REGEX = /(([a-z]+:\/\/)?(([a-z0-9\-]+\.)+([a-z]{2}|aero|arpa|biz|com|coop|edu|gov|info|int|jobs|mil|museum|name|nato|net|org|pro|travel|local|internal))(:[0-9]{1,5})?(\/[a-z0-9_\-\.~]+)*(\/([a-z0-9_\-\.]*)(\?[a-z0-9+_\-\.%=&]*)?)?(#[a-zA-Z0-9!$&'()*+.=-_~:@/?]*)?)(\s+|$)/gi

전체 도우미 (선택적 핸들 바 지원)는 요점 # 1654670에 있습니다.


11
유한 한 TLD를 계속 나열하는 것은 좋지 않습니다. 새로운 TLD를 계속 생성하기 때문입니다.
Maxy-B

동의하다. 때때로 우리는 TLD와 함께 업데이트 가능한 코드가 필요합니다. 실제로 TLD를 정규식에 추가하거나 코드의 동적 코드 업데이트 TLD를 추가하는 스크립트를 빌드 할 수 있습니다. 인생에는 TLD 및 시간대와 같이 표준화되어야 할 것들이 있습니다. 실제 주소 사용 사례에 대해 기존 "TLD"확인 가능한 URL을 확인하는 것이 유한 한 제어입니다.
Edward Chan JW

답변:


217

먼저 URL과 일치하는 좋은 정규식이 필요합니다. 이것은 어렵다. 참조 여기 , 여기여기 :

... 거의 모든 것이 유효한 URL입니다. 나누기위한 구두점 규칙이 있습니다. 문장 부호가 없으면 여전히 유효한 URL이 있습니다.

RFC를주의 깊게 확인하고 "유효하지 않은"URL을 구성 할 수 있는지 확인하십시오. 규칙은 매우 유연합니다.

예를 들어 :::::유효한 URL입니다. 경로는":::::" 입니다. 꽤 바보 같은 파일 이름이지만 유효한 파일 이름입니다.

또한 /////유효한 URL입니다. netloc ( "hostname")은 ""입니다. 경로는 "///"입니다. 다시, 바보. 또한 유효합니다. 이 URL은"///" 어느 것이 동등한 지 .

같은 "bad://///worse/////" 것이 완벽하게 유효합니다. 멍청하지만 유효합니다.

어쨌든이 대답은 최고의 정규 표현식을 제공하는 것이 아니라 JavaScript로 텍스트 안에 문자열 줄 바꿈을 수행하는 방법에 대한 증거입니다.

좋아, 그냥 이것을 사용하십시오 : /(https?:\/\/[^\s]+)/g

다시 말하지만 이것은 나쁜 정규 표현식 입니다. 많은 오 탐지가있을 것입니다. 그러나이 예제에는 충분합니다.

function urlify(text) {
  var urlRegex = /(https?:\/\/[^\s]+)/g;
  return text.replace(urlRegex, function(url) {
    return '<a href="' + url + '">' + url + '</a>';
  })
  // or alternatively
  // return text.replace(urlRegex, '<a href="$1">$1</a>')
}

var text = 'Find me at http://www.example.com and also at http://stackoverflow.com';
var html = urlify(text);

console.log(html)

// html now looks like:
// "Find me at <a href="http://www.example.com">http://www.example.com</a> and also at <a href="http://stackoverflow.com">http://stackoverflow.com</a>"

결론적으로 시도해보십시오.

$$('#pad dl dd').each(function(element) {
    element.innerHTML = urlify(element.innerHTML);
});

4
"많은 오 탐지"의 일부 예는이 답변을 크게 향상시킬 것입니다. 그렇지 않으면 미래의 Google 직원들에게는 일부 FUD가 남아있을 수 있습니다.
cmcculloh

나는 당신이 함수를 두 번째 매개 변수로 전달할 수 있다는 것을 몰랐습니다 .replace: |
Aamir Afridi 2016 년

4
좋지만 문장 부호가 뒤 따르는 "잘못된" text="Find me at http://www.example.com, and also at http://stackoverflow.com."결과는 두 개의 404가됩니다. 일부 사용자는이 사실을 알고 있으며 구두점을 피하기 위해 URL 뒤에 공백 뒤에 공백을 추가하지만, 내가 사용하는 대부분의 링크 (Gmail, etherpad, phabricator)는 후행 구두점을 URL과 구분합니다.
skierpage

텍스트에 이미 고정 된 URL이 포함 된 경우 removeAnchors (text) 함수를 사용할 수 있습니다. {var div = $ ( '<div> </ div>'). html (text); div.find ( 'a'). contents (). unwrap (); return div.text (); } 반환 text.replace 전에 앵커를 먼저 제거하려면
Muneeb Mirza

텍스트에 이미 앵커 URL이 포함되어 있으면 jquery를 사용하여 앵커를 제거하고 있지만 Angular를 사용하고 있습니다. Angular에서 앵커를 어떻게 제거 할 수 있습니까?
Sachin Jagtap

132

다음은 정규식으로 사용한 결과입니다.

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

URL에 후행 문장 부호는 포함되지 않습니다. 초승달의 기능은 매력처럼 작동합니다. :)

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

4
마지막으로 가장 명백한 경우에 실제로 작동하는 정규식! 북마크가 필요합니다. 이것을 찾을 때까지 Google 검색에서 수천 개의 예제를 테스트했습니다.
Ismael

6
간단하고 좋은! 그러나 컴파일은 비싸기 때문에 외부 에서 urlRegex정의해야합니다 . linkify
BM

1
이것은 전체 URL을 감지하지 못합니다 : disney.wikia.com/wiki/Pua_(Moana)
Jry9972

1
()각 문자 목록에 추가 했는데 지금 작동합니다.
기 illa F.

3
www로 시작하는 URL을 감지하지 못합니다. 예 : www.facebook.com
CraZyDroiD

51

나는이 문제를 꽤 오랫동안 봤다.이를 달성하기 위해 꽤 강력한 정규식을 사용하는 android.text.util.Linkify 안드로이드 메소드가 있다는 것이 나에게 일어났다. 운 좋게도 안드로이드는 오픈 소스입니다.

서로 다른 유형의 URL을 일치시키기 위해 몇 가지 다른 패턴을 사용합니다. 여기에서 모두 찾을 수 있습니다. http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.0_r1/android/text/util/Regex.java#Regex에서 . 0WEB_URL_PATTERN

WEB_URL_PATTERN과 일치하는 URL, 즉 RFC 1738 사양을 준수하는 URL에 관심이있는 경우 다음을 사용할 수 있습니다.

/((?:(http|https|Http|Https|rtsp|Rtsp):\/\/(?:(?:[a-zA-Z0-9\$\-\_\.\+\!\*\'\(\)\,\;\?\&\=]|(?:\%[a-fA-F0-9]{2})){1,64}(?:\:(?:[a-zA-Z0-9\$\-\_\.\+\!\*\'\(\)\,\;\?\&\=]|(?:\%[a-fA-F0-9]{2})){1,25})?\@)?)?((?:(?:[a-zA-Z0-9][a-zA-Z0-9\-]{0,64}\.)+(?:(?:aero|arpa|asia|a[cdefgilmnoqrstuwxz])|(?:biz|b[abdefghijmnorstvwyz])|(?:cat|com|coop|c[acdfghiklmnoruvxyz])|d[ejkmoz]|(?:edu|e[cegrstu])|f[ijkmor]|(?:gov|g[abdefghilmnpqrstuwy])|h[kmnrtu]|(?:info|int|i[delmnoqrst])|(?:jobs|j[emop])|k[eghimnrwyz]|l[abcikrstuvy]|(?:mil|mobi|museum|m[acdghklmnopqrstuvwxyz])|(?:name|net|n[acefgilopruz])|(?:org|om)|(?:pro|p[aefghklmnrstwy])|qa|r[eouw]|s[abcdeghijklmnortuvyz]|(?:tel|travel|t[cdfghjklmnoprtvwz])|u[agkmsyz]|v[aceginu]|w[fs]|y[etu]|z[amw]))|(?:(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[0-9])))(?:\:\d{1,5})?)(\/(?:(?:[a-zA-Z0-9\;\/\?\:\@\&\=\#\~\-\.\+\!\*\'\(\)\,\_])|(?:\%[a-fA-F0-9]{2}))*)?(?:\b|$)/gi;

다음은 소스의 전체 텍스트입니다.

"((?:(http|https|Http|Https|rtsp|Rtsp):\\/\\/(?:(?:[a-zA-Z0-9\\$\\-\\_\\.\\+\\!\\*\\'\\(\\)"
+ "\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,64}(?:\\:(?:[a-zA-Z0-9\\$\\-\\_"
+ "\\.\\+\\!\\*\\'\\(\\)\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,25})?\\@)?)?"
+ "((?:(?:[a-zA-Z0-9][a-zA-Z0-9\\-]{0,64}\\.)+"   // named host
+ "(?:"   // plus top level domain
+ "(?:aero|arpa|asia|a[cdefgilmnoqrstuwxz])"
+ "|(?:biz|b[abdefghijmnorstvwyz])"
+ "|(?:cat|com|coop|c[acdfghiklmnoruvxyz])"
+ "|d[ejkmoz]"
+ "|(?:edu|e[cegrstu])"
+ "|f[ijkmor]"
+ "|(?:gov|g[abdefghilmnpqrstuwy])"
+ "|h[kmnrtu]"
+ "|(?:info|int|i[delmnoqrst])"
+ "|(?:jobs|j[emop])"
+ "|k[eghimnrwyz]"
+ "|l[abcikrstuvy]"
+ "|(?:mil|mobi|museum|m[acdghklmnopqrstuvwxyz])"
+ "|(?:name|net|n[acefgilopruz])"
+ "|(?:org|om)"
+ "|(?:pro|p[aefghklmnrstwy])"
+ "|qa"
+ "|r[eouw]"
+ "|s[abcdeghijklmnortuvyz]"
+ "|(?:tel|travel|t[cdfghjklmnoprtvwz])"
+ "|u[agkmsyz]"
+ "|v[aceginu]"
+ "|w[fs]"
+ "|y[etu]"
+ "|z[amw]))"
+ "|(?:(?:25[0-5]|2[0-4]" // or ip address
+ "[0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\\.(?:25[0-5]|2[0-4][0-9]"
+ "|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(?:25[0-5]|2[0-4][0-9]|[0-1]"
+ "[0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}"
+ "|[1-9][0-9]|[0-9])))"
+ "(?:\\:\\d{1,5})?)" // plus option port number
+ "(\\/(?:(?:[a-zA-Z0-9\\;\\/\\?\\:\\@\\&\\=\\#\\~"  // plus option query params
+ "\\-\\.\\+\\!\\*\\'\\(\\)\\,\\_])|(?:\\%[a-fA-F0-9]{2}))*)?"
+ "(?:\\b|$)";

정말 화려하고 싶다면 이메일 주소도 테스트 할 수 있습니다. 이메일 주소의 정규식은 다음과 같습니다.

/[a-zA-Z0-9\\+\\.\\_\\%\\-]{1,256}\\@[a-zA-Z0-9][a-zA-Z0-9\\-]{0,64}(\\.[a-zA-Z0-9][a-zA-Z0-9\\-]{0,25})+/gi

추신 : 위 정규식이 지원하는 최상위 도메인은 2007 년 6 월 현재 최신 상태입니다. 최신 목록을 보려면 https://data.iana.org/TLD/tlds-alpha-by-domain.txt 를 확인 하십시오. .


3
대소 문자를 구분하지 않는 정규 표현식이 있으므로 a-zA-Zand 를 지정할 필요가 없습니다 http|https|Http|Https|rtsp|Rtsp.
Ry-

4
이것은 좋지만, 내가 그것을 사용할지 확신하지 못합니다. 대부분의 유스 케이스에서는 하드 코딩 된 TLD 목록에 의존하는 접근법을 사용하는 것보다 약간의 오탐을 받아들입니다. 코드에 TLD를 나열하면 언젠가는 더 이상 사용되지 않을 것이라고 보장하고 피할 수 있다면 향후 코드에 대한 필수 유지 관리를 작성하지 않을 것입니다.
Mark Amery

3
이것은 101 %의 시간 동안 작동하지만 불행히도 앞에 공백이없는 URL을 찾습니다. hello@mydomain.com에서 일치하는 항목을 실행하면 'mydomain.com'이 붙습니다. 이전에 공간이있는 경우에만 잡을 수 있도록 개선 할 수있는 방법이 있습니까?
Deminetix

또한, 이것은 사용자가 입력 한 URL을 잡기에 완벽합니다
Deminetix

grepcode.com가 더 이상 최대 것을 참고 여기가 내가 무엇을 생각 안드로이드 소스 코드에서 적절한 장소에 대한 링크입니다. 나는 안드로이드가 사용하는 정규식이 2013 년 이후 업데이트되었을 수도 있지만 (원래 게시물) 2015 년 이후 업데이트되지 않은 것으로 보이므로 새로운 TLD가 누락 될 수 있습니다.
James

19

초승달 기준 답변을

http : //가 없는 http : // 또는 www에 의한 링크를 감지하려는 경우 당신은 다음을 사용할 수 있습니다

function urlify(text) {
    var urlRegex = /(((https?:\/\/)|(www\.))[^\s]+)/g;
    //var urlRegex = /(https?:\/\/[^\s]+)/g;
    return text.replace(urlRegex, function(url,b,c) {
        var url2 = (c == 'www.') ?  'http://' +url : url;
        return '<a href="' +url2+ '" target="_blank">' + url + '</a>';
    }) 
}

이것은 좋은 해결책이지만 텍스트에 이미 href가 없어야하는지 확인하고 싶습니다. 이 정규식 = /((?!href)((https?:\/\/)|(www\.)|(mailto:))[^\s]+)/gi 시도했지만 작동하지 않습니다. 당신이 그것을 도울 수 있습니까 또는 왜 위의 정규 표현식이 작동하지 않습니까?
Sachin Jagtap

반환 된 출력에 target = "_ blank"도 추가 한 것이 좋습니다. 이 버전은 내가 원하는 것입니다. 대부분의 링크를 얻을 수있을 정도로 상단에 아무것도 없습니다 (그렇지 않으면 Linkifyjs를 사용합니다).
Michael Kubler

18

NPM 의이 라이브러리는 매우 포괄적 인 것 같습니다 https://www.npmjs.com/package/linkifyjs

Linkify는 작지만 포괄적 인 JavaScript 플러그인으로 일반 텍스트에서 URL을 찾아 HTML 링크로 변환합니다. 유효한 모든 URL 및 이메일 주소와 함께 작동합니다.


4
내 프로젝트에서 linkifyjs 구현을 완료했으며 환상적입니다. Linkifyjs가이 질문에 대한 답이어야합니다. 다른 하나는 github.com/twitter/twitter-text입니다
Uber

6

이미지를 렌더링하기 위해 기능을 더욱 향상시킬 수 있습니다.

function renderHTML(text) { 
    var rawText = strip(text)
    var urlRegex =/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;   

    return rawText.replace(urlRegex, function(url) {   

    if ( ( url.indexOf(".jpg") > 0 ) || ( url.indexOf(".png") > 0 ) || ( url.indexOf(".gif") > 0 ) ) {
            return '<img src="' + url + '">' + '<br/>'
        } else {
            return '<a href="' + url + '">' + url + '</a>' + '<br/>'
        }
    }) 
} 

또는 실제 크기 이미지로 연결되는 썸네일 이미지의 경우 :

return '<a href="' + url + '"><img style="width: 100px; border: 0px; -moz-border-radius: 5px; border-radius: 5px;" src="' + url + '">' + '</a>' + '<br/>'

그리고 여기에 기존 HTML을 제거하여 균일 성을 위해 텍스트 문자열을 사전 처리하는 strip () 함수가 있습니다.

function strip(html) 
    {  
        var tmp = document.createElement("DIV"); 
        tmp.innerHTML = html; 
        var urlRegex =/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;   
        return tmp.innerText.replace(urlRegex, function(url) {     
        return '\n' + url 
    })
} 

2
let str = 'https://example.com is a great site'
str.replace(/(https?:\/\/[^\s]+)/g,"<a href='$1' target='_blank' >$1</a>")

쇼트 코드 빅 워크! ...

결과:-

 <a href="https://example.com" target="_blank" > https://example.com </a>

1

기존 npm 패키지가 있습니다 : url-regex , yarn add url-regex또는 함께 설치하고 npm install url-regex다음과 같이 사용하십시오 :

const urlRegex = require('url-regex');

const replaced = 'Find me at http://www.example.com and also at http://stackoverflow.com or at google.com'
  .replace(urlRegex({strict: false}), function(url) {
     return '<a href="' + url + '">' + url + '</a>';
  });

0

tmp.innerText가 정의되지 않았습니다. tmp.innerHTML을 사용해야합니다

function strip(html) 
    {  
        var tmp = document.createElement("DIV"); 
        tmp.innerHTML = html; 
        var urlRegex =/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;   
        return tmp.innerHTML .replace(urlRegex, function(url) {     
        return '\n' + url 
    })

0

이 시도:

function isUrl(s) {
    if (!isUrl.rx_url) {
        // taken from https://gist.github.com/dperini/729294
        isUrl.rx_url=/^(?:(?:https?|ftp):\/\/)?(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,}))\.?)(?::\d{2,5})?(?:[/?#]\S*)?$/i;
        // valid prefixes
        isUrl.prefixes=['http:\/\/', 'https:\/\/', 'ftp:\/\/', 'www.'];
        // taken from https://w3techs.com/technologies/overview/top_level_domain/all
        isUrl.domains=['com','ru','net','org','de','jp','uk','br','pl','in','it','fr','au','info','nl','ir','cn','es','cz','kr','ua','ca','eu','biz','za','gr','co','ro','se','tw','mx','vn','tr','ch','hu','at','be','dk','tv','me','ar','no','us','sk','xyz','fi','id','cl','by','nz','il','ie','pt','kz','io','my','lt','hk','cc','sg','edu','pk','su','bg','th','top','lv','hr','pe','club','rs','ae','az','si','ph','pro','ng','tk','ee','asia','mobi'];
    }

    if (!isUrl.rx_url.test(s)) return false;
    for (let i=0; i<isUrl.prefixes.length; i++) if (s.startsWith(isUrl.prefixes[i])) return true;
    for (let i=0; i<isUrl.domains.length; i++) if (s.endsWith('.'+isUrl.domains[i]) || s.includes('.'+isUrl.domains[i]+'\/') ||s.includes('.'+isUrl.domains[i]+'?')) return true;
    return false;
}

function isEmail(s) {
    if (!isEmail.rx_email) {
        // taken from http://stackoverflow.com/a/16016476/460084
        var sQtext = '[^\\x0d\\x22\\x5c\\x80-\\xff]';
        var sDtext = '[^\\x0d\\x5b-\\x5d\\x80-\\xff]';
        var sAtom = '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+';
        var sQuotedPair = '\\x5c[\\x00-\\x7f]';
        var sDomainLiteral = '\\x5b(' + sDtext + '|' + sQuotedPair + ')*\\x5d';
        var sQuotedString = '\\x22(' + sQtext + '|' + sQuotedPair + ')*\\x22';
        var sDomain_ref = sAtom;
        var sSubDomain = '(' + sDomain_ref + '|' + sDomainLiteral + ')';
        var sWord = '(' + sAtom + '|' + sQuotedString + ')';
        var sDomain = sSubDomain + '(\\x2e' + sSubDomain + ')*';
        var sLocalPart = sWord + '(\\x2e' + sWord + ')*';
        var sAddrSpec = sLocalPart + '\\x40' + sDomain; // complete RFC822 email address spec
        var sValidEmail = '^' + sAddrSpec + '$'; // as whole string

        isEmail.rx_email = new RegExp(sValidEmail);
    }

    return isEmail.rx_email.test(s);
}

또한 다음과 같은 URL을 인식 google.com, http://www.google.bla, http://google.bla, www.google.bla하지만google.bla


0

이와 같은 정규식을 사용하여 일반 URL 패턴을 추출 할 수 있습니다.

(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})

보다 정교한 패턴이 필요한 경우 이와 같은 라이브러리를 사용하십시오.

https://www.npmjs.com/package/pattern-dreamer


목적은 (?:www\.|(?!www))무엇입니까? 왜 wwwww.com유효하지 않아야 합니까?
Toto

네 말이 맞아 실제로 나는 많은 사람들이 정규 표현식을 사용하는 것처럼 그것을 가져갔습니다. 위의 링크 된 라이브러리를 사용하는 것이 좋습니다. 우리는 URL 탐지에서 많은 경우를 고려해야하므로 정규 표현식이 더 복잡해야합니다.
Kang Andrew

0

일반적인 객체 지향 솔루션

DOM을 직접 조작 할 수없는 angular와 같은 프레임 워크를 사용하는 나와 같은 사람들을 위해 문자열을 가져 와서 url/ 의 배열을 반환하는 함수를 만들었습니다.plainText 원하는 UI 표현을 만드는 데 사용할 수있는 객체 .

URL 정규식

내가 사용한 URL 일치를 위해 (약간 적응) h0mayun 정규 표현식을 ./(?:(?:https?:\/\/)|(?:www\.))[^\s]+/g

내 기능도 같은 URL의 끝에서 구두점을 삭제 .하고 ,난을 적용하는 것이 들어 나는 종료 합법적 인 URL보다는 실제 문장이 될 것입니다 더 자주 믿는다 (다른 답변을 잘 설명으로하지만이 될 수있다! 이것은 엄격한 과학이 아니다) 일치하는 URL에 정규식을 따릅니다 /^(.+?)([.,?!'"]*)$/.

타입 스크립트 코드

    export function urlMatcherInText(inputString: string): UrlMatcherResult[] {
        if (! inputString) return [];

        const results: UrlMatcherResult[] = [];

        function addText(text: string) {
            if (! text) return;

            const result = new UrlMatcherResult();
            result.type = 'text';
            result.value = text;
            results.push(result);
        }

        function addUrl(url: string) {
            if (! url) return;

            const result = new UrlMatcherResult();
            result.type = 'url';
            result.value = url;
            results.push(result);
        }

        const findUrlRegex = /(?:(?:https?:\/\/)|(?:www\.))[^\s]+/g;
        const cleanUrlRegex = /^(.+?)([.,?!'"]*)$/;

        let match: RegExpExecArray;
        let indexOfStartOfString = 0;

        do {
            match = findUrlRegex.exec(inputString);

            if (match) {
                const text = inputString.substr(indexOfStartOfString, match.index - indexOfStartOfString);
                addText(text);

                var dirtyUrl = match[0];
                var urlDirtyMatch = cleanUrlRegex.exec(dirtyUrl);
                addUrl(urlDirtyMatch[1]);
                addText(urlDirtyMatch[2]);

                indexOfStartOfString = match.index + dirtyUrl.length;
            }
        }
        while (match);

        const remainingText = inputString.substr(indexOfStartOfString, inputString.length - indexOfStartOfString);
        addText(remainingText);

        return results;
    }

    export class UrlMatcherResult {
        public type: 'url' | 'text'
        public value: string
    }

0

http : // 또는 ftp없이 http : // 또는 링크를 감지하거나 마지막에 구두점을 제거하는 것과 같은 다른 가능한 경우이 코드를 살펴보십시오.

https://jsfiddle.net/AndrewKang/xtfjn8g3/

사용하는 간단한 방법은 NPM을 사용하는 것입니다

npm install --save url-knife
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.