Düz URL'leri bağlantılar ile nasıl değiştirebilirim?


454

Belirli bir metnin içindeki URL'leri eşleştirmek ve bunları HTML bağlantıları yerine koymak için aşağıdaki işlevi kullanıyorum. Normal ifade harika çalışıyor, ancak şu anda sadece ilk eşleşmenin yerini alıyorum.

Tüm URL'yi nasıl değiştirebilirim? Ben exec komutunu kullanmalıyım sanırım , ama nasıl yapılacağını gerçekten anlamadım.

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

Yanıtlar:


351

Öncelikle, URL'leri ayrıştırmak için kendi normal ifadenizi yuvarlamak korkunç bir fikirdir . Bu birileri debug, yazılı ve olduğu yaygın bir yeterince sorun olduğunu düşünün gerekir test göre, bunun için bir kütüphane RFC'lerle . URI'ler karmaşıktır - Node.js'de URL ayrıştırma koduna ve URI şemalarındaki Wikipedia sayfasına göz atın .

URL'leri ayrıştırma söz konusu olduğunda bir ton uç nokta vardır: uluslararası alan adları , gerçek ( .museum) ve var olmayan ( .etc) TLD'ler, parantezler dahil tuhaf noktalama işaretleri, URL'nin sonundaki noktalama işaretleri, IPV6 ana bilgisayar adları vb.

Ben baktım bir ton ait kütüphaneler ve bazı olumsuzlukları rağmen kullanarak birkaç değer vardır:

Bu görev için hızlı bir şekilde diskalifiye ettiğim kütüphaneler:

Normal bir ifadede ısrar ederseniz, en kapsamlı olanı Bileşen'den URL normal ifadesidir, ancak var olmayan bazı iki harfli TLD'leri yanlış bir şekilde tespit eder.


3
Yorum URL regexp from Componentyapılmaması üzücü, ne yaptığı hakkında bazı açıklamalar yardımcı olacaktır. Autolinker.jsçok iyi yorumlanmış ve testleri var. urlize.jsİçinde bağlantılı kütüphane Vebjørn Ljosa cevabı o testleri bulunmasa da, özellikli ve bakımlı görünüyor.
Sam Hasler

1
Regex101.com otomatik olarak regexp "açıklar" , ama bununla iyi şanslar :) Ayrıca hızlı bir şekilde geçersiz TLD (aynı bağlantı) ile bir başarısızlık davası buldum.
Dan Dascalescu

1
@SamHasler: TLD'ler ve IDN'ler alanında Autolinker'ın geliştirilmesi gerekiyor. Bazı testler eklendi .
Dan Dascalescu

2
Kimsenin John Gruber'ın URL normal ifadesini koruma çabalarından bahsetmediğinden merak ediyor . Sorunun tek / ideal çözümü değil, her durumda, kendi çözümünüzü yuvarlıyorsanız araştırmaya değer. Sadece bunu referans olarak eklemek istedim.
oelna

2
Bu bir göz atın @DanDascalescu markdown-it.github.io/linkify-it . Bu kütüphane tam olarak tek bir göreve odaklanır - metindeki bağlantı kalıplarını tespit eder. Ama umarım iyi yapar. Örneğin, astral karakterler de dahil olmak üzere doğru unicode desteğine sahiptir. Ve uluslararası TLD'leri destekliyor.
Vitaly

285

URL'leri bağlantılarla değiştirme (Genel Sorunun Cevabı)

Sorudaki düzenli ifade çok sayıda uç durumu kaçırıyor . URL'leri algılarken, uluslararası alan adlarını, .museumURL gibi ve sonundaki yeni TLD'leri , parantezleri ve diğer noktalama işaretlerini ve diğer birçok büyük durumu ele alan özel bir kütüphane kullanmak her zaman daha iyidir . Diğer sorunların bir açıklaması için Jeff Atwood'un URL'lerle İlgili Sorun adlı blog gönderisine bakın .

URL eşleştirme kütüphanelerin en iyi özeti olduğunu Dan Dascalescu en Yanıt100
(2014 Şubat itibariyle)


"Normal ifadeyi birden fazla eşleşmenin yerine koy" (Belirli sorunun cevabı)

Genel eşlemeyi etkinleştirmek için normal ifadenin sonuna "g" ekleyin:

/ig;

Ancak bu, normal ifadenin yalnızca ilk eşleşmenin yerini aldığı sorudaki sorunu giderir. Bu kodu kullanmayın.


150

Travis'in kodunda bazı küçük değişiklikler yaptım (sadece gereksiz yeniden açıklamalardan kaçınmak için - ama ihtiyaçlarım için harika çalışıyor, çok güzel bir iş!):

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
gömülü nesnelere ve iframe'lere zarar vermemek için bu kodu nasıl düzenleyebilirsiniz .. (youtube gömülü nesneleri ve iframe'ler)
Pradyut Bhattacharya

5
Kodda, burada e-posta adresleriyle eşleşen bir hata var. daha karmaşık alan adlarıyla (e-posta@example.co.uk) eşleşmesi [a-zA-Z]{2,6}için satırları boyunca bir şeyler (?:[a-zA-Z]{2,6})+okumalıdır.
Roshambo

1
Bazı sorunlarla karşılaştım; ilk önce sadece http: // veya http: // www (boşluk olmadan www bile SO yanlış görünüyor bu ayrışır görünüşte) bir bağlantı oluşturur. Ve http: // www. alan adı . com (boşluklar olmadan) bir boş bağlantı ve ardından href alanında bağlı bir bağlantı kapatma etiketi olan bir bağlantı oluşturur.
Alfred

1
http://Veya içermeyen URL'ler ne olacak www? Bu, bu tür URL'ler için işe yarar mı?
Nathan

2
Mailto sorununu çözmek için orijinal gönderiyi düzenlemeye çalıştım, ancak düzenleme yapmak için en az 6 karakter eklemeliyim. Ama bu satırı değiştirirseniz: replacePattern3 = /(\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,6})/gim;bununla replacePattern3 = /(\w+@[a-zA-Z_]+?(\.[a-zA-Z]{2,6})+)/gim;o düzeltmeleri mailto sorunu :)
yourdeveloperfriend

70

Linkify()Yukarıdaki Travis kodunda bazı optimizasyonlar yapıldı . Ayrıca, alt alan adı türü biçimli e-posta adreslerinin eşleşmeyeceği bir hatayı da düzelttim (örn. Example@domain.co.uk).

Buna ek olarak, ben Stringsınıf prototiplemek için uygulama değiştirildi böylece öğeleri şöyle eşleştirilebilir:

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

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

Her neyse, işte senaryo:

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

Benim görüşüme göre en iyi, Prototip fonksiyonları işleri çok daha temiz hale getirir :)
MRVDOG

Bu e-posta adresleri ile çalışmıyor gibi görünüyor: info@some-thing.com some.thing@example.com vb ..
Marco Gagliardi

@MarcoGagliardi İyi yakaladın. Sabit.
Roshambo

1
Bu "git clone aaaa@bitbucket.org/ooo/bbb-cc-dd.git " dizesi için çalışmaz . Dizeyi parçalara ayırdı ve bunun gibi birden çok bağlantı oluşturdu "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
+Gibi e-posta kullanıcı adlarında çalışmaz foo+bar@domain.com. E-posta deseni ile sabitledim /[\w.+]+@[a-zA-Z_-]+?(?:\.[a-zA-Z]{2,6})+/gim( +ilk köşeli parantezlere dikkat edin ), ancak bunun başka bir şeyi kırar mı bilmiyorum.
dchacke

24

Teşekkürler, bu çok yardımcı oldu. Ayrıca, URL gibi görünen şeyleri birbirine bağlayacak bir şey istedim - temel bir gereklilik olarak, http: // protokol öneki mevcut olmasa bile www.yahoo.com gibi bir şey bağlardı. Temel olarak, "www." mevcutsa, bağlantı kurar ve http: // olduğunu varsayar. Ayrıca e-postaların mailto: linklere dönüşmesini istedim. ÖRNEK: www.yahoo.com www.yahoo.com'a dönüştürülür

Sonunda bulduğum kod (bu sayfadaki kod ve çevrimiçi bulduğum diğer şeyler ve kendi başıma yaptığım diğer şeyler kombinasyonu):

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
}

2. değişiklikte, (^ | [^ /]) kısmı, ilk URL'de zaten bir URL bağlanmışsa çift bağlantıyı önlemek için, zaten // - ile önceden eklenmemişse www.whatever.com'un yerini alır. Ayrıca, rexeksin o bölümündeki ilk "veya" koşul olan www.whatever.com dizenin başında olabilir.

Bu, yukarıda gösterildiği gibi Jesse P gibi bir jQuery eklentisi olarak entegre edilebilir - ancak özellikle mevcut bir DOM öğesine etki etmeyen düzenli bir işlev istedim, çünkü sahip olduğum metni alıp DOM'a ekliyorum ve Ben eklemeden önce metnin "linkified" olmasını istiyorum, bu yüzden metni bu işlevden geçiriyorum. Harika çalışıyor.


1
Düz "www.etkialani.com" ile tek başına eşleşen 2. kalıpla ilgili bir sorun var. Sorun, url'de bir tür yönlendirici olduğunda aşağıdaki gibi olur: & 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 - bu durumda bağlantı otomatik olarak tekrar bağlanır. Hızlı bir düzeltme, "/" içeren reddedilen listenin arkasına "f" karakterini eklemektir. Yani ifade: replacePattern2 = /(^|[^\/fülür)(www\.[\S Genişletilmiş+
b|$)))

Yukarıdaki kod, kenar durumlar için birçok testte başarısız olacaktır. URL'leri tespit ederken, özel bir kütüphaneye güvenmek daha iyidir. İşte nedeni .
Dan Dascalescu

2
Ben sadece bazı web bağlantıları zaten bir href bağlantıları var bir dize üzerinde koştu. Bu durumda, mevcut çalışma bağlantılarını bozmaz.
AdamJones

17

URL'leri tanımlamak yanıltıcıdır, çünkü genellikle noktalama işaretleri ile çevrilidir ve kullanıcılar URL'nin tam biçimini sıklıkla kullanmazlar. URL'leri köprülerle değiştirmek için birçok JavaScript işlevi vardır, ancak urlizePython tabanlı web çerçevesi Django'daki filtrenin yanı sıra çalışan bir işlev bulamadım . Bu nedenle Django'nun urlizeişlevini JavaScript'e taşıdım:

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

Bir örnek:

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

İkinci argüman, doğruysa, rel="nofollow"eklenmeye neden olur . Üçüncü argüman, doğruysa, HTML'de özel anlamı olan karakterlerden kaçar. README dosyasına bakın .


Ayrıca html kaynağı ile çalışır: www.web.com <a href = "https: // github. Com"> url </ a> bazı metinler
Paulius Zaliaduonis

@Paulius: seçeneği django_compatiblefalse olarak ayarlarsanız, bu kullanım durumunu biraz daha iyi işler.
Vebjorn Ljosa

Django's urlizeTLD'leri düzgün bir şekilde desteklemez (en azından GitHub'daki JS portunu desteklemez). O bir kütüphane kolları TLD'leri düzgün olan Ben Alman JavaScript Linkify .
Dan Dascalescu

URL "http" veya "www" ile başlamasa bile, üst düzey alan adlarıyla URL'leri algılama desteği.
Vebjorn Ljosa

10

AAA.bbb'yi tanımak için emailAddressPattern'de Roshambo String.linkify () 'de bir değişiklik yaptım. @ Ccc.ddd adresleri

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

Yukarıdaki kod, kenar durumlar için birçok testte başarısız olacaktır. URL'leri tespit ederken, özel bir kütüphaneye güvenmek daha iyidir. İşte nedeni .
Dan Dascalescu

9

Google'da yeni bir şey aradım ve bununla karşılaştım:

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

demo: http://jsfiddle.net/kachibito/hEgvc/1/

Normal bağlantılar için gerçekten iyi çalışıyor.


Burada "Normal bağlantılar" nedir? Demonuzun çatalına buradan bakın: jsfiddle.net/hEgvc/27 İnsanlar ortaya çıkarılacak ve bunu kolay bir şekilde yapacaktır. URI, RFC3986'ya göre kolay bir şey değildir ve yalnızca "Normal bağlantıları" kapsamak istiyorsanız, en azından bu normal ifadeyi izlemenizi öneririz: ^ (([^: /? #] +):)? (// ([ ^ /? #] *))? ([^? #] *) (\? ([^ #] *))? (# (*.))?
Ivan

2
Ben biçiminde bir şey ifade http://example.com/folder/folder/folder/veya https://example.org/blahorada kullanım örneklerinin 95-99% maç olacak sadece tipik olmayan çılgın URL biçimi - vb. Bunu dahili bir yönetim alanı için kullanıyorum, bu yüzden kenar vakaları veya hashlink'leri yakalamak için fantezi bir şeye ihtiyacım yok.
Dejenere


5

Bu çözüm, diğerlerinin çoğu gibi çalışır ve aslında bunlardan biriyle aynı normal ifadeyi kullanır, ancak bir HTML Dizesi döndürmek yerine, bu, A öğesini ve ilgili metin düğümlerini içeren bir belge parçası döndürür.

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

Daha eski IE ve textContent desteği ile bazı uyarılar var.

işte bir demo.


2
@DanDascalescu Battaniyeyi aşağıya düşürmek yerine, söz konusu kenar vakalarınızı sağlayabilir.
rlemon

İhtiyacım var mı? URL'ler için Bileşen normal ifadesine göz atın . Ama ısrar ederseniz, Ben Alman'ın linkify test paketine karşı koşun . Örneğin, urlize için başarısız testlere katkıda bulunmaya başladım , ancak kısa süre sonra bunun sadece ciddi kütüphane çabaları için yapmaya değer olduğunu fark ettim. Saygılarımızla, yukarıdaki yanıt, URL'leri doğru bir şekilde ayrıştırmaya çalışan açık kaynaklı bir kitaplık değil, bir StackOverflow cevabıdır.
Dan Dascalescu

2
bu yüzden kenar durumlar var. olağanüstü. bu cevaplar hala başkaları için yararlı olabilir ve battaniyenin altını oymak aşırıya kaçıyor gibi görünüyor. Diğer yorum yaptığınız ve görünüşte downvoted ettik cevaplar do faydalı bilgiler içeriyor (yanı sıra Cevabınız). herkes söz konusu davalara karşı gelmeyecek ve herkes bir kütüphane kullanmak istemeyecek.
rlemon

Kesinlikle. Normal ifadelerin sınırlamalarını anlamayanlar, ilk normal ifadeyi en çok oylanan cevaptan mutlu bir şekilde gözden geçirecek ve onunla birlikte çalışacak olanlardır. Bunlar kütüphaneleri en çok kullananlardır.
Dan Dascalescu

1
Peki, tercih ettiğiniz çözüm olmayan normal ifadeyle her cevabı aşağı oylamanın gerekçesi nasıl?
rlemon

4

Daha kısa bağlantı göstermeniz (yalnızca alan adı), ancak aynı uzun URL ile göstermeniz gerekiyorsa, yukarıda yayınlanan Sam Hasler'in kod sürümünde yaptığım değişikliği deneyebilirsiniz

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

Kayıt Örneği: /(\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>");
}

Aşağıda bazı test edilmiş dizeler verilmiştir:

  1. Beni www.google.com adresinde bul
  2. www
  3. Beni www. http://www.com
  4. Beni takip et: http://www.nishantwork.wordpress.com
  5. http://www.nishantwork.wordpress.com
  6. Beni takip et: http://www.nishantwork.wordpress.com
  7. https://stackoverflow.com/users/430803/nishant

Not: wwwGeçerli olarak geçmek istemiyorsanız reg reg: /(\b((https?|ftp|file):\/\/|(www))[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig


Yukarıdaki kod, kenar durumlar için birçok testte başarısız olacaktır. URL'leri tespit ederken, DAİMA özel bir kütüphaneye güvenmek daha iyidir. İşte nedeni .
Dan Dascalescu

3

URI karmaşıklığı ile ilgili uyarılar not edilmelidir, ancak sorunuzun basit cevabı şudur:
Her eşleşmeyi değiştirmek için /gbayrağı RegEx'in sonuna eklemeniz gerekir :
/(\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/>(");
}

basit örnek


2

Basit tutun! Sahip olabileceğinizin yerine sahip olamayacağınızı söyleyin :)

Yukarıda belirtildiği gibi, URL'ler özellikle '?' Den sonra oldukça karmaşık olabilir ve hepsi bir 'www' ile başlamaz. Örneğinmaps.bing.com/something?key=!"£$%^*()&lat=65&lon&lon=20

Yani, tüm uç vakaları karşılamayacak ve bakımı zor olacak karmaşık bir normal ifadeye sahip olmak yerine, pratikte benim için iyi çalışan bu çok daha basit olana ne dersiniz.

Eşleşme

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

www. (anything but a space)+

'Bir şey' olduğu yerde [^'"<>\s] ... temelde açgözlü bir eşleşme, size bir alan, alıntı, köşeli ayraç veya satır sonu ile tanışmak

Ayrıca:

O URL biçiminde zaten olmadığını kontrol etmeyi unutmayın, metin örneğin içeren href="..."veyasrc="..."

Ref = nofollow ekle (uygunsa)

Bu çözüm, yukarıda belirtilen kütüphaneler kadar "iyi" değildir, ancak çok daha basittir ve pratikte iyi çalışır.

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

Uluslararası alan adları ve astral karakter desteği ile doğru URL algılaması önemsiz bir şey değildir. linkify-itkütüphane birçok koşuldan normal ifade oluşturur ve son boyut yaklaşık 6 kilobayttır :). Şu anda kabul edilen cevapta atıfta bulunulan tüm kütüphanelerden daha doğrudur.

Tüm uç vakaları canlı olarak kontrol etmek ve bunları test etmek için linkify-it demosuna bakın .

HTML kaynağını doğrulamanız gerekiyorsa, önce kaynağını ayrıştırmalı ve her metin belirtecini ayrı ayrı yinelemelisiniz.



0

Bunun tam tersini yapmak ve sadece URL'ye html bağlantıları yapmak zorunda kaldım, ama normal ifadenizi değiştirdim ve bir cazibe gibi çalışıyor, teşekkürler :)

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

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

Normal ifadenizin amacını görmüyorum. Her şeyin yerine her şeyi koyan her şeyi eşleştirir. Aslında kodunuz hiçbir şey yapmaz.
Chad Grant

8
İnsanların düzenlemeyi bitirmesine izin vermek için yorum yapmak için beklemeliyim sanırım. afedersiniz.
Chad Grant

0

Travitron'un yukarıdaki cevabındaki e-posta tespiti benim için işe yaramadı, bu yüzden aşağıdaki ile değiştirdim / değiştirdim (C # kodu).

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

Bu, " ad.secondname@one.two.three.co.uk " gibi e-posta adreslerine izin verir .


Yukarıdaki kod, kenar durumlar için birçok testte başarısız olacaktır. URL'leri tespit ederken, DAİMA özel bir kütüphaneye güvenmek daha iyidir. İşte nedeni .
Dan Dascalescu

Teşekkürler, @DanDascalescu Genellikle, aşırı genellemek her zaman daha iyidir.
Uwe Keim

0

Birkaç kaynaktan girdikten sonra şimdi iyi çalışan bir çözümüm var. Kendi değiştirme kodunuzu yazmakla ilgisi vardı.

Cevap .

Keman .

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
Yukarıdaki kod (ve genel olarak en düzenli ifadeler) uç durumlar için çok sayıda testten başarısız olacaktır. URL'leri tespit ederken, özel bir kütüphaneye güvenmek daha iyidir. İşte nedeni .
Dan Dascalescu

Dan, böyle bir kütüphane var mı? Bu durumda, yine de yukarıdaki regex ile eşleşiriz, böylece giriş gibi bir şey çöp gibi başka bir kütüphane çöpü onaylasa bile kod asla çöp çıktısı veremez.
Mike Mestnik


0

İşte benim çözümüm:

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

Aşağıdaki işlevi deneyin:

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

Aşağıda Çözümü Deneyin

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;
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.