プレーン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スキームの Wikipediaページを確認してください。

URLの解析に関しては、多数のエッジケースがあります。国際ドメイン名、実際の(.museum)対存在しない(.etc)TLD、かっこなどの奇妙な句読点、URLの末尾の句読点、IPV6ホスト名などです。

私が見てきたトンライブラリ、およびいくつかの欠点にもかかわらず、使用して、いくつかの価値があります。

このタスクですぐに失格したライブラリ:

正規表現を主張する場合、最も包括的なのはComponentからURL正規表現ですが、存在しない2文字のTLDを見ると誤って検出されます。


3
URL regexp from Componentコメントされていないのは残念です、それが何をしているのかについてのいくつかの説明が役に立つでしょう。Autolinker.js非常によくコメントされ、テストがあります。urlize.js中にリンクされたライブラリ Vebjorn Ljosaの答えは、それがテストを持っていないが、また、高機能とよく維持に見えます。
サムハスラー2014

1
Regex101.comは自動的に正規表現を「説明」しますが、幸運を祈ります:)また、無効なTLD(同じリンク)の失敗例もすぐに見つかりました。
Dan Dascalescu、2014

1
@SamHasler:TLDとIDN領域でオートリンカーを改善する必要があります。いくつかのテストを追加しました
Dan Dascalescu、2014

2
URLの正規表現パターンを維持するためのJohn Gruberの取り組みについて誰も触れなかったことに興味があります。それは問題の唯一の/理想的な解決策ではありませんが、独自の解決策を展開している場合は、調査する価値があります。これを参照として追加したかっただけです。
oelna 2014年

2
これを見てください@DanDascalescu markdown-it.github.io/linkify-itを。このライブラリは、テキスト内のリンクパターンを検出するという1つのタスクに重点を置いています。しかし、私はそれがうまくいくことを願っています。たとえば、アストラル文字を含む、適切なUnicodeサポートがあります。そして、それは国際的なTLDをサポートします。
Vitaly

285

URLをリンクに置き換える(一般的な問題への回答)

質問の正規表現は、多くのエッジケースを見逃しています。URLを検出するときは、国際的なドメイン名、のような新しいTLD .museum、かっこ、およびURLの末尾と末尾にあるその他の句読点、およびその他の多くのエッジケースを処理する専用ライブラリを使用することをお勧めします。他のいくつかの問題の説明については、Jeff Atwoodのブログ投稿The URL With URLを参照してください。

URLマッチングライブラリ最適な要約は、Dan 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、2011

1
私はいくつかの問題に遭遇しました。最初にhttp://またはhttp:// www(スペースなしではwwwが SOでもこれを間違って解析しているように見えます)だけでリンクが作成されます。そしてhttp:// wwwとリンクします。ドメイン。com(スペースなし)は、1つの空のリンクを作成し、次にhrefフィールドにアンカー終了タグが添付されたリンクを作成します。
アルフレッド

1
何のないURLに関するhttp://www?これはそのようなURLで機能しますか?
Nathan

2
元の投稿を編集してmailtoの問題を修正しようとしましたが、編集するには少なくとも6文字を追加する必要があります。しかし、あなたは、この行を変更した場合:replacePattern3 = /(\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,6})/gim;これでreplacePattern3 = /(\w+@[a-zA-Z_]+?(\.[a-zA-Z]{2,6})+)/gim;その修正のmailto問題:)
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 2014年

info@some-thing.com some.thing@example.comなど。:このような電子メールアドレスでは動作しないようです
マルコ・ガリアルディ

@MarcoGagliardi良いキャッチ。修繕。
Roshambo 2014年

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> "
ジェビン

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
}

2番目の置換では、(^ | [^ /])部分がwww.whatever.comの前に//が付いていない場合にのみ置き換えられます-最初の置換でURLがすでにリンクされている場合の二重リンクを回避します。また、www.whatever.comが文字列の先頭にある可能性もあります。これは、正規表現のその部分の最初の「または」条件です。

これは、上記のJesse PのようにjQueryプラグインとして統合できますが、既存のDOM要素に作用しない通常の関数が特に必要でした。持っているテキストを取得してDOMに追加し、追加する前にテキストを「リンク化」したいので、この関数にテキストを渡します。よく働く。


1
2番目のパターンには問題があります。これは、プレーンな「www.domain.com」だけに一致します。この問題は、URLに次のような何らかのリファラーが含まれている場合に発生します。 -20&linkCode = ur2&camp = 1789&creative = 9325-この場合、リンクは再び自動リンクされます。簡単な修正は、「/」を含む否定リストの後に文字「f」を追加することです。したがって、式は次のようになります。replacePattern2 = /(^|[^\/f])(www\.[\S]+(\b|$))/gim
Redtopia

上記のコードは、エッジケースの多くのテストに失敗します。URLを検出する場合は、専用のライブラリに依存することをお勧めします。これが理由です。
Dan Dascalescu 2014

2
一部のWebリンクに既にhrefリンクが含まれている文字列に対して実行しました。この場合、既存の作業中のリンクを台無しにするのに失敗します。
AdamJones 14

17

URLは句読点で囲まれていることが多く、ユーザーは完全な形式のURLを頻繁に使用しないため、URLの識別は注意が必要です。URLをハイパーリンクに置き換えるためのJavaScript関数は多数存在しますurlizeが、PythonベースのWebフレームワーク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;"

2番目の引数がtrueの場合、rel="nofollow"挿入されます。3番目の引数がtrueの場合、HTMLで特別な意味を持つ文字をエスケープします。READMEファイルを参照してください。


www.web.com <a href = "https:// github。com"> url </ a> some text
Paulius Zaliaduonis

@Paulius:オプションdjango_compatibleをfalseに設定すると、そのユースケースが少し良く処理されます。
Vebjorn Ljosa、2012

Django urlizeはTLDを適切にサポートしていません(少なくともGitHubのJSポートはサポートしていません)。TLDを適切に処理するライブラリは、Ben AlmanのJavaScript Linkifyです
Dan Dascalescu 2014

URLが「http」または「www」で始まらない場合でも、追加のトップレベルドメインでURLを検出するためのサポートが追加されました。
Vebjorn Ljosa、2014

10

Roahambo String.linkify()を変更してemailAddressPatternを変更し、aaa.bbb。@ ccc.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>');
    };
}

上記のコードは、エッジケースの多くのテストに失敗します。URLを検出する場合は、専用のライブラリに依存することをお勧めします。これが理由です。
Dan Dascalescu、2014

9

私はGoogleで新しいものを検索し、これに遭遇しました:

$('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人々はカバーされていないものをカバーし、これを簡単な方法で作成します。RFC3986のとおり、URIは簡単なものではありません。「通常のリンク」のみをカバーしたい場合は、少なくともこの正規表現に従うことをお勧めします。^(([^:/?#] +):)?(//([ ^ /?#] *))?([^?#] *)(\?([^#] *))?(#(。*))?
Ivan

2
私は形式には何も意味しhttp://example.com/folder/folder/folder/たりhttps://example.org/blahそこから使用例95から99パーセントにマッチしますちょうどあなたの典型的な非狂気のURL形式-など。私はこれを内部の管理領域に使用しているので、エッジケースやハッシュリンクをキャッチするために特別なことをする必要はありません。
2016年


5

このソリューションは他の多くのソリューションと同様に機能し、実際にはそれらの1つと同じ正規表現を使用しますが、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テストスイートに対して実行してください。私は失敗したテスト、例えばurlizeへの貢献を始めましたが、すぐにそれが真剣なライブラリの努力のためにそうするだけの価値があることに気づきました。当然のことながら、上記はStackOverflowの回答であり、URLを正しく解析しようとするオープンソースのライブラリではありません。
Dan Dascalescu 2014

2
エッジケースがあります。素晴らしい。これらの回答はまだ他の人に役立つ可能性があります。あなたがコメントし、反対票を投じたと思われる他の回答に、役立つ情報(および回答)含まれています。誰もが上記のケースに反対するわけではなく、誰もがライブラリを使用したいと思うわけではありません。
rlemon 14

丁度。正規表現の制限を理解していないのは、最も支持されている答えから最初の正規表現を喜んで読み飛ばして実行する人です。それらは、ライブラリを最も使用する必要がある人々です。
Dan Dascalescu 2014

1
しかし、あなたの優先するソリューションではない正規表現ですべての回答に反対票を投じる正当化はどうでしょうか?
rlemon 14

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有効なものとして渡したくない場合は、以下の正規表現を使用してください。 /(\b((https?|ftp|file):\/\/|(www))[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig


上記のコードは、エッジケースの多くのテストに失敗します。URLを検出するときは、常に専用のライブラリに依存することをお勧めします。これが理由です。
Dan Dascalescu 2014

3

URIの複雑さに関する警告に注意
する必要がありますが、質問に対する簡単な答えは次のとおりです。すべての一致を置き換えるに/gは、RegExの最後にフラグを追加する必要があります。
/(\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は特に「?」の後はかなり複雑になる可能性があり、すべてが「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ソースをリンクする必要がある場合は、まずそれを解析し、各テキストトークンを個別に反復する必要があります。


1

さらに別のJavaScriptライブラリを作成しましたが、非常に敏感であり、誤検知が最小限に抑えられており、高速でサイズが小さいため、より良いものになる可能性があります。私は現在積極的にメンテナンスを行っているので、デモページでテストして、どのように機能するかを確認してください。

リンク:https : //github.com/alexcorvi/anchorme.js


素晴らしいライブラリ。どうもありがとうございました!
SerdarDeğirmenci18年

0

私は反対のことをしなければならず、HTMLリンクをURLだけにする必要がありましたが、私はあなたの正規表現を変更しました、そしてそれは魅力のように機能します、ありがとう:)

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

ソース= 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 2014

ありがとう、@ DanDascalescu通常、過剰に一般化することは常に優れています。
Uwe Keim 2014

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 2014

ダン、そのような図書館はありますか?この場合でも、上記の正規表現に一致しているため、(別のライブラリがゴミを有効なURL / URIとして認定している場合でも)ゴミのようなものを入力として使用しても、コードはゴミを出力できません。
Mike Mestnik 2015年


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.