0

以下のコードは、URL の文字列からのテキストをチェックし、クリック可能なリンクに変換しています。

画像へのリンクがある場合、 < a> タグに rel="image" を追加するように取得しようとしています。YouTube の動画がある場合は、< a> タグに rel="youtube" を追加します。

文字列にリンクが 1 つしかない場合は正常に機能します。複数ある場合、すべてのリンクは最後のリンクの rel を取得します。

$text = "http://site.com a site www.anothersite.com/ http://imgur.com/image.png http://youtu.be/UyxqmghxS6M here is another site";

$linkstring = preg_replace('/(http|ftp)?+(s)?:?(\/\/)?+(www.)?((\w|\.)+)+\.(com|org|net|mil|edu|COM|ORG|NET|MIL|EDU|be|info|co)+(\/)?(\S+)?/i', '<a rel="iframe" href="\0">\0</a>', $text ); 
if(preg_match('/((http:\/\/)?(?:youtu\.be\/|(?:[a-z]{2,3}\.)?youtube\.com\/v\/)([\w-]{11}).*|http:\/\/(?:youtu\.be\/|(?:[a-z]{2,3}\.)?youtube\.com\/watch(?:\?|#\!)v=)([\w-]{11}).*)/i', $linkstring, $vresult)) {
    $pattern = "/(http|ftp)?+(s)?:?(\/\/)?+(www.)?((\w|\.)+)+\.(com|org|net|mil|edu|COM|ORG|NET|MIL|EDU|be|info|co)+(\/)?(\S+)?/i";
    $replacement = '<a rel="youtube" href="\0">\0</a>';
    $text2 = preg_replace($pattern, $replacement, $text);
    $type= 'youtube';
} elseif(preg_match('/(http(s?):)?|([\/|.|\w|\s])*\.(?:jpg|gif|png|jpeg|bmp)/i', $linkstring, $vresult)) {
    $pattern = "/(http|ftp)?+(s)?:?(\/\/)?+(www.)?((\w|\.)+)+\.(com|org|net|mil|edu|COM|ORG|NET|MIL|EDU|be|info|co)+(\/)?(\S+)?/i";
    $replacement = '<a rel="image" href="\0">\0</a>';
    $text2 = preg_replace($pattern, $replacement, $text);
    $type= 'image';
} else {
    $type = 'none';
}
echo $text, "<br />";
echo $text2, "<br />";
echo $linkstring, "<br />";
echo $type, "<br />";

YouTube または画像リンクと同じ正規表現に一致するように $pattern を変更しようとしましたが、URL の後にテキスト全体のリンクが作成されてしまいます。

例:

$text = "http://site.com a site www.anothersite.com/ http://imgur.com/image.png http://youtu.be/UyxqmghxS6M here is another site";

$linkstring = preg_replace('/(http|ftp)?+(s)?:?(\/\/)?+(www.)?((\w|\.)+)+\.(com|org|net|mil|edu|COM|ORG|NET|MIL|EDU|be|info|co)+(\/)?(\S+)?/i', '<a rel="iframe" href="\0">\0</a>', $text ); 
if(preg_match('/((http:\/\/)?(?:youtu\.be\/|(?:[a-z]{2,3}\.)?youtube\.com\/v\/)([\w-]{11}).*|http:\/\/(?:youtu\.be\/|(?:[a-z]{2,3}\.)?youtube\.com\/watch(?:\?|#\!)v=)([\w-]{11}).*)/i', $linkstring, $vresult)) {
    $pattern = "/((http:\/\/)?(?:youtu\.be\/|(?:[a-z]{2,3}\.)?youtube\.com\/v\/)([\w-]{11}).*|http:\/\/(?:youtu\.be\/|(?:[a-z]{2,3}\.)?youtube\.com\/watch(?:\?|#\!)v=)([\w-]{11}).*)/i";
    $replacement = '<a rel="youtube" href="\0">\0</a>';
    $text2 = preg_replace($pattern, $replacement, $text);
    $type= 'youtube';
} else {
    $type = 'none';
}
4

1 に答える 1

0

残念ながら、RegEx を機能させて、出力がどのように見えるかを正確に確認することはできません (結果の文字列を説明するだけでなく、結果の文字列を投稿すると役立つ場合があります)。

ただし、行うことは次のとおりです。if ステートメントの最初のスニペットでは、文字列に YouTube リンクまたは画像リンクが含まれているかどうかを確認します。しかし、その後、情報をまったく使用せずに、最初の文字列全体に対して preg_replace を再度使用します。もちろん、以前に preg_match で見つけたものだけでなく、すべてのリンクを置き換えます (呼び出しは完全に無関係であるため)。

したがって、2番目のアプローチは実際には優れています。ただし、同じパターンに一致する文字列部分のみが置き換えられるため、その場合は if 句はまったく必要ないと思います。リンクの後に完全な文字列を取得する理由は、RegExes で貪欲と呼ばれるものです。これは、考えられる 2 つの YouTube パターンを で終了するために発生します.*。これは、URL の残りの部分と一致する可能性がありますが、常に可能な限り多くを取り込みます。.は任意の文字に一致するため、それが文字列の残りの部分です。そのため、まず最初に、文字の考慮をどこで停止するかを正規表現に伝える必要があります。たとえば、URL はスペースまたは引用符で終わると言えます。だから代わりに

(youtubepattern1).*|(youtubepattern2).*

あなたは試すことができます

((youtubepattern1|youtubepattern2).*)["\s]

しかし、URL の直後に複数の引用符がある場合、または文字列の後ろにさらに空白がある場合、貪欲さは依然として問題です (最後の空白または引用符まですべてが含まれるため)。(PHP の正規表現メソッドで) インタープリターに .* を貪欲に扱うように指示するには、疑問符を追加します。

((youtubepattern1|youtubepattern2).*?)["\s]

\0また、おそらく置換を usingから using nowに変更する必要があります\1(\0 には URL を終了する空白または引用符が含まれるため)。

于 2012-09-21T06:54:53.887 に答える