2

文字列を取得して解析し、画像の URL を a<img src="image">に、リンクを に置き換える関数を作成しようとしています<a href="link">link</a>

これは私がしたことです:

var __urlRegex = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;
var __imgRegex = /^ftp|http|https?:\/\/(?:[a-z\-]+\.)+[a-z]{2,6}(?:\/[^\/#?]+)+\.(?:jpe?g|gif|png)$/ig;

function parseURL($string){
    var exp = __urlRegex;
    return $string.replace(exp,function(match){
            if(__imgRegex.test(match,contents)){
                return '<img src="'+contents+'" width="200" />';
            }
            else{
                return '<a href="'+contents+'" target="_blank">'+contents+'</a>';
            }
        }
    );
}

いくつかのテストを行ったとき、正規表現は正常に機能します。ただし、実装時に、いくつかの奇妙なマンボジャンボが発生しています。5つの画像URLを投げると、1番目は画像として解析されますが、2番目はリンクとして解析され、これが交互に続きます!!

どこが間違っているのですか?

テストに使用したサンプル文字列:

This is a kitten http://s3.amazonaws.com/rapgenius/filepicker%2FvCleswcKTpuRXKptjOPo_kitten.jpg
with a sibling which is also a kitten http://s3.amazonaws.com/rapgenius/filepicker%2FvCleswcKTpuRXKptjOPo_kitten.jpg
and a sister which is also a kitten http://s3.amazonaws.com/rapgenius/filepicker%2FvCleswcKTpuRXKptjOPo_kitten.jpg
and lots of kittens
http://s3.amazonaws.com/rapgenius/filepicker%2FvCleswcKTpuRXKptjOPo_kitten.jpg
http://s3.amazonaws.com/rapgenius/filepicker%2FvCleswcKTpuRXKptjOPo_kitten.jpg
http://s3.amazonaws.com/rapgenius/filepicker%2FvCleswcKTpuRXKptjOPo_kitten.jpg
http://s3.amazonaws.com/rapgenius/filepicker%2FvCleswcKTpuRXKptjOPo_kitten.jpg

そして、これは私が得る出力です

<p>This is a kitten <img src="http://s3.amazonaws.com/rapgenius/filepicker%2FvCleswcKTpuRXKptjOPo_kitten.jpg" width="200">
with a sibling which is also a kitten <a href="http://s3.amazonaws.com/rapgenius/filepicker%2FvCleswcKTpuRXKptjOPo_kitten.jpg" target="_blank">http://s3.amazonaws.com/rapgenius/filepicker%2FvCleswcKTpuRXKptjOPo_kitten.jpg</a>
and a sister which is also a kitten <img src="http://s3.amazonaws.com/rapgenius/filepicker%2FvCleswcKTpuRXKptjOPo_kitten.jpg" width="200">
and lots of kittens
undefined
<img src="http://s3.amazonaws.com/rapgenius/filepicker%2FvCleswcKTpuRXKptjOPo_kitten.jpg" width="200">
<a href="http://s3.amazonaws.com/rapgenius/filepicker%2FvCleswcKTpuRXKptjOPo_kitten.jpg" target="_blank">http://s3.amazonaws.com/rapgenius/filepicker%2FvCleswcKTpuRXKptjOPo_kitten.jpg</a>
<img src="http://s3.amazonaws.com/rapgenius/filepicker%2FvCleswcKTpuRXKptjOPo_kitten.jpg" width="200"></p>
4

1 に答える 1

3

RegExp.test()から

同じグローバル正規表現インスタンスで複数回呼び出されたテストは、前の一致を超えて進みます。

RegExp.lastIndex

次の一致を開始するインデックスを指定する読み取り/書き込み整数プロパティ。

ドキュメントで指定されているように、lastIndexはtest()が照合を開始する位置を格納します。

したがって、基本的に RegExp のインスタンスがある場合、test()を呼び出すたびにlastIndexが進みます。最初の一致が見つかると、それを超えて別の一致を見つけようとします。まあ、もう何もないので、falseを返します。lastIndexは に再設定され、 test()への0次の呼び出しは最初から開始され、trueが返されます...

したがって、test()が常に次の文字列の先頭から一致を開始するようにするには、 lastIndexプロパティをにリセットする必要があります。0

__imgRegex.lastIndex=0;

JSFiddle DEMO

function parseURL($string){

    var exp = __urlRegex;
    return $string.replace(exp,function(match){
            __imgRegex.lastIndex=0;
            if(__imgRegex.test(match)){
                return '<img src="'+match+'" class="thumb" />';
            }
            else{
                return '<a href="'+match+'" target="_blank">'+match+'</a>';
            }
        }
    );
}

編集:

正規表現がhttp://google.com画像として正しく一致していませんでした。また、引数が 1 つだけであることをテストします。

__imgRegex.test('http://google.com') //true

最初にテキストがリンクであることを確認するため、リンクかどうかを再度確認する必要はありません。画像の拡張子があるかどうかを確認するだけで済みます。

var __imgRegex = /\.(?:jpe?g|gif|png)$/i;
于 2013-09-20T17:31:24.503 に答える