Detectar URLs em texto com JavaScript

151

Alguém tem sugestões para detectar URLs em um conjunto de strings?

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

Atualização: Acabei usando esse regex para detecção de link ... Aparentemente, vários anos depois.

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

O ajudante completo (com suporte opcional ao guidão) está na essência # 1654670 .

arbales
fonte
11
Provavelmente não é uma boa ideia tentar listar um conjunto finito de TLDs, pois eles continuam criando novos.
precisa saber é o seguinte
Aceita. Às vezes, precisamos de um código que possa ser atualizado com os TLDs. Na verdade, pode-se criar um script para anexar o TLD ao regex ou aos TLDs de atualização dinâmica de código no código. Há coisas na vida que devem ser padronizadas, como TLDs e fuso horário. O controle finito pode ser bom para verificar o URL verificável dos "TLDs" existentes para o caso de uso de endereço do mundo real.
Edward Chan JW

Respostas:

217

Primeiro, você precisa de uma boa regex que corresponda aos URLs. Isso é difícil de fazer. Veja aqui , aqui e aqui :

... quase tudo é um URL válido. Existem algumas regras de pontuação para dividi-lo. Na ausência de pontuação, você ainda tem um URL válido.

Verifique o RFC com cuidado e veja se você pode criar um URL "inválido". As regras são muito flexíveis.

Por exemplo, :::::é um URL válido. O caminho é ":::::". Um nome de arquivo bastante estúpido, mas um nome de arquivo válido.

Além disso, /////é um URL válido. O netloc ("hostname") é "". O caminho é "///". Mais uma vez, estúpido. Também válido. Esse URL normaliza para "///" qual é o equivalente.

Algo como "bad://///worse/////" é perfeitamente válido. Burro, mas válido.

De qualquer forma, esta resposta não pretende fornecer o melhor regex, mas sim uma prova de como fazer a quebra de cadeia dentro do texto, com JavaScript.

OK, então vamos apenas usar este: /(https?:\/\/[^\s]+)/g

Novamente, este é um mau regex . Terá muitos falsos positivos. No entanto, é bom o suficiente para este exemplo.

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

Então, em suma, tente:

$$('#pad dl dd').each(function(element) {
    element.innerHTML = urlify(element.innerHTML);
});
Crescent Fresh
fonte
4
Alguns exemplos dos "muitos falsos positivos" melhorariam bastante esta resposta. Caso contrário, os futuros Googlers ficarão com algum (talvez válido?) FUD.
cmcculloh
Eu nunca soube que você pode passar a função como segundo parâmetro para .replace: |
Aamir Afridi
4
É bom, mas faz a coisa "errada" com text="Find me at http://www.example.com, and also at http://stackoverflow.com."resultados de pontuação à direita em dois 404s. Alguns usuários estão cientes disso e adicionam um espaço após os URLs antes da pontuação, para evitar quebras, mas a maioria dos vinculadores que eu uso (Gmail, etherpad, phabricator) separa a pontuação final do URL.
Skierpage 30/07/2015
Caso o texto já contenha um URL ancorado, você pode usar a função removeAnchors (texto) {var div = $ ('<div> </div>') .html (texto); div.find ('a'). contents (). desembrulhar (); retornar div.text (); } Para primeiras âncoras Remova antes text.replace retorno
Muneeb Mirza
Se o texto já contém um URL ancorado, você está usando o jquery para remover a âncora, mas estou usando o Angular. Como posso remover a âncora no Angular?
Sachin Jagtap
132

Aqui está o que eu acabei usando como meu regex:

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

Isso não inclui pontuação à direita no URL. A função de Crescent funciona como um encanto :) então:

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>';
    });
}
Niaz Mohammed
fonte
4
Finalmente, um regex que realmente funciona no caso mais óbvio! Este merece um favorito. Testei milhares de exemplos da pesquisa do Google até encontrar isso.
Ismael
6
Simples e agradável! Mas o que urlRegexdeve ser definido fora linkify como compilar é caro.
BM
1
Isso falha ao detectar o URL completo: disney.wikia.com/wiki/Pua_(Moana)
Jry9972
1
Eu adicionei ()em cada lista de caracteres e funciona agora.
Guillaume F.
3
ele falha ao detectar um URL começando com apenas www. por exemplo: www.facebook.com
CraZyDroiD 11/11
51

Pesquisei esse problema por um bom tempo e ocorreu-me que existe um método Android, android.text.util.Linkify, que utiliza algumas expressões bastante robustas para fazer isso. Felizmente, o Android é de código aberto.

Eles usam alguns padrões diferentes para combinar diferentes tipos de URLs. Você pode encontrá-los todos aqui: 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

Se você está preocupado apenas com os URLs que correspondem aos WEB_URL_PATTERN, ou seja, URLs que estão em conformidade com a especificação RFC 1738, você pode usar isso:

/((?:(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;

Aqui está o texto completo da fonte:

"((?:(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|$)";

Se você quiser ser realmente chique, também pode testar endereços de email. A regex para endereços de email é:

/[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

PS: Os domínios de nível superior suportados pelo regex acima estão atualizados em junho de 2007. Para obter uma lista atualizada, você deve verificar https://data.iana.org/TLD/tlds-alpha-by-domain.txt .

Adão
fonte
3
Como você tem uma expressão regular que não diferencia maiúsculas de minúsculas, não precisa especificar a-zA-Ze http|https|Http|Https|rtsp|Rtsp.
Ry-
4
Isso é legal, mas não tenho certeza se alguma vez usaria. Na maioria dos casos de uso, prefiro aceitar alguns falsos positivos do que usar uma abordagem que se baseia em uma lista codificada de TLDs. Se você listar TLDs em seu código, estará garantindo que ele ficará obsoleto um dia e prefiro não incluir manutenção futura obrigatória em meu código, se eu puder evitá-lo.
Mark Amery
3
Isso funciona 101% do tempo, infelizmente também encontra URLs que não são precedidos por um espaço. Se eu executar uma correspondência em [email protected], ele pegará 'mydomain.com'. Existe uma maneira de melhorar isso e capturá-lo apenas se houver um espaço antes dele?
Deminetix
Também a nota, este é perfeito para a captura entrou usuário urls
Deminetix
Observe que o grepcode.com não está mais ativo, eis o que eu acho que é um link para o lugar certo no código-fonte do Android. Acho que o regex que o Android está usando pode ser atualizado desde 2013 (postagem original), mas não parece ter sido atualizado desde 2015 e, portanto, pode estar faltando alguns TLDs mais recentes.
James
19

Baseado na resposta Crescent Fresh

se você deseja detectar links com http: // OU sem http: // e por www. você pode usar o seguinte

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>';
    }) 
}
h0mayun
fonte
Essa é uma boa solução, mas também quero verificar se o texto já não deve conter href. Eu tentei este regex = /((?!href)((https?:\/\/)|(www\.)|(mailto:))[^\s)+)/gi mas não está funcionando. Você pode me ajudar com isso ou por que o regex acima não está funcionando.
Sachin Jagtap
Gosto que você também adicionou target = "_ blank" à saída retornada. Esta versão é o que eu queria. Nada muito exagerado (caso contrário, eu usaria o Linkifyjs) apenas o suficiente para obter a maioria dos links.
Michael Kubler
18

Essa biblioteca no NPM parece bastante abrangente https://www.npmjs.com/package/linkifyjs

O Linkify é um plugin JavaScript pequeno, porém abrangente, para encontrar URLs em texto sem formatação e convertê-los em links HTML. Funciona com todos os URLs e endereços de email válidos.

Dan Kantor
fonte
4
Acabei de implementar o linkifyjs no meu projeto e é fantástico. Linkifyjs deve ser a resposta para esta pergunta. O outro é olhar para github.com/twitter/twitter-text
Uber Schnoz
6

A função também pode ser aprimorada para renderizar imagens:

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

ou para uma imagem em miniatura vinculada a uma imagem de tamanho completo:

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

E aqui está a função strip () que pré-processa a sequência de texto para uniformidade, removendo qualquer html existente.

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 
    })
} 
Gautam Sharma
fonte
2
let str = 'https://example.com is a great site'
str.replace(/(https?:\/\/[^\s]+)/g,"<a href='$1' target='_blank' >$1</a>")

Código curto grande trabalho! ...

Resultado:-

 <a href="https://example.com" target="_blank" > https://example.com </a>
Kashan Haider
fonte
1

Existe um pacote npm: url-regex , basta instalá-lo com yarn add url-regexou npm install url-regexe usar da seguinte maneira:

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

tmp.innerText é indefinido. Você deve usar o 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 
    })
Án Bình Trọng
fonte
0

tente isto:

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

também irá reconhecer URLs como google.com, http://www.google.bla, http://google.bla, www.google.blanão, masgoogle.bla

kofifus
fonte
0

Você pode usar uma regex como essa para extrair padrões de URL normais.

(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,})

Se você precisar de padrões mais sofisticados, use uma biblioteca como esta.

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

Kang Andrew
fonte
Qual é o propósito (?:www\.|(?!www))? Por que deveria wwwww.comser inválido?
Totó
Você está certo. Na verdade, eu apenas peguei como muitos usam o regex. Eu recomendo usar a biblioteca vinculada acima. Deveríamos considerar muitos casos na detecção de URL, para que o regex seja mais complicado.
Kang Andrew #
0

Solução orientada a objetos genéricos

Para pessoas como eu que usam estruturas como angulares que não permitem a manipulação direta do DOM, criei uma função que pega uma string e retorna uma matriz de url/ plainTextobjetos que podem ser usados ​​para criar qualquer representação de interface do usuário que você desejar.

Regex de URL

Para correspondência de URL, usei h0mayunregex (ligeiramente adaptado) :/(?:(?:https?:\/\/)|(?:www\.))[^\s]+/g

Minha função também descarta caracteres de pontuação do final de uma URL .e ,acredito que com mais frequência será uma pontuação real do que uma URL legítima finalizada (mas poderia ser! Isso não é ciência rigorosa, pois outras respostas explicam bem). regex a seguir nos URLs correspondentes /^(.+?)([.,?!'"]*)$/.

Código datilografado

    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
    }
eddyP23
fonte
0

Se você deseja detectar links com http: // OR sem http: // OR ftp OU outros casos possíveis, como remover a pontuação final no final, dê uma olhada neste código.

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

Uma maneira simples de usar isso é usar o NPM

npm install --save url-knife
Kang Andrew
fonte