0

正規表現が苦手です。テキスト内のハイパーリンクへのリンクを変更したい

例えば

Hello http://stackoverflow.com
Hello www.stackoverflow.com

スタックオーバーフローをリンクさせたい

Hello <a href='http://stackoverflow.com'>http://stackoverflow.com</a>
Hello <a href='http://www.stackoverflow.com'>www.stackoverflow.com</a>

これを使った

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

しかし、これはhttp://でのみです

少し早いですがお礼を

4

2 に答える 2

6

他の人が言ったように、最初に「リンク」とは何かを定義する必要があります。(このコンテキストでは、「リンク」は「ハイパーリンク」の略であることに注意してください。そのため、あなたの文章は意味がありません。) 2 つの例を考慮して、Uniform Resource Identifier (URI)完全修飾ドメイン名を一致させたいと考えています。 (FQDN)代わりに。

これを行うには、RFC 3986、付録 Bにある正規表現を使用する必要があります。 </p>

^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?

– 単語境界で一致するものに変更し、 の後に FQDN とオプションのポート番号のみを受け入れ、空白 ( )//で停止します。\s

      ,----scheme----.   ,-Fully Qualified Domain Name-.,-port.,--path--.,---query----.,fragment
      |              |   |                             ||     ||        ||            ||       |
(^|\s)(([^:/?#\s]+):)?(//([A-Za-z0-9-]+\.)+[A-Za-z0-9-]+(:\d+)?([^?#\s]*)(\?([^#\s]*))?(#(\S*))?

次に、スキーム部分をオプションにすることができます–</p>

                          |
                          v
(^|\s)((([^:/?#\s]+):)?//)?(([A-Za-z0-9-]+\.)+[A-Za-z0-9-]+(:\d+)?([^?#\s]*)(\?([^#\s]*))?(#(\S*))?

– これを正規表現リテラルとして記述します (式のスラッシュは区切り文字として機能するため、エスケープする必要があります)。

/(^|\s)((([^:\/?#\s]+):)?\/\/)?(([A-Za-z0-9-]+\.)+[A-Za-z0-9-]+)(:\d+)?([^?#\s]*)(\?([^#\s]*))?(#(\S*))?/

( IDNも一致させたい場合があります。JSX:regexp.js とその Unicode 文字プロパティのサポートが役立ちます。文字列からすべての文字を削除する方法を参照してください。また、FQDN 部分式の前に、(\w+@)?プロキシ アクセス用の URI でのユーザー名の省略可能で非推奨の送信。)

次に、対応する要素と一致するすべての文字列 ( lobal 修飾子) を置き換えることができます。ga

var rx = /(^|\s)(((([^:\/?#\s]+):)?\/\/)?(([A-Za-z0-9-]+\.)+[A-Za-z0-9-]+)(:\d+)?([^?#\s]*)(\?([^#\s]*))?(#(\S*))?)/g;

str = str.replace(rx,
  function (match, optionalWhitespace, uri, scheme, p4, protocol, fqdn, p7, port,
            path, query, queryVal, fragment, fragId) {
    return (optionalWhitespace ? optionalWhitespace : '')
      + '<a href="' + (protocol ? uri : 'http://' + uri)
      + '" target="_blank">' + uri + '<\/a>';
  });

ここで、FQDN プレフィックスしか表示されない場合は、セキュリティで保護されていない Web サイトのドメイン名であると想定し、先頭にhttp://. そうしないと、属性の URI 参照が、Web サイトに存在するhref可能性のあるパスを参照し、ドメイン名を名前 ( ) として持つことになり、おそらくこれは望ましくありません。http://your-site.example/other-site.example.com

あなたの場合、この表現があまりにも多く一致する可能性はありますが、そうではありません。できるだけ多くの入力でテストし、必要に応じて調整します。下位互換性が問題にならない場合は、効率と名前の少ないパラメーターのために非キャプチャ括弧( ) を使用します。(?:…)詳細については、ECMAScript サポート マトリックスを参照してください。

FQDN 部分 (括弧で囲まれた部分) の取得([A-Za-z0-9-]+\.)+[A-Za-z0-9-]+はオプションです。たとえば、スタック オーバーフロー、ウィキペディア、Twitter、または Facebook へのリンクなどに適したアイコンを先頭に追加するなど、a要素に属性値を与えて特別な方法で書式設定するために使用することができます。class

target属性の使用を再検討することもできます ( Strict (X)HTML の場合は、削除する必要があります)。ユーザーは、リンク ターゲットがどこで開いているかを制御できないことを、おそらく親切に受け止めません。代わりに、タイトル、アイコン、カーソルなどの形でヒントを提供してください。

于 2012-05-30T16:22:06.557 に答える
0

次のコードを使用します。

var exp = /(((?:(?:https?|ftp|file):)?\/\/)?(?:[\w-]+\.)?[\w-]+\.\w{2,5}(?:\/[^\s\/]*)*)/ig;
return str.replace(exp, function(_, link, protocol){
    return link.link(protocol ? link : "http://" + link);
}); 
于 2012-05-30T13:23:48.647 に答える