4

ですから、SOには関連する質問がたくさんあることは知っていますが、どれも私が探しているものではありません。ユーザーが作成した投稿からのテキストURLをリンクに変換するPHP関数を実装しようとしています。ページの下部にあるDaringFireballの「改良された」正規表現を使用しています:http://daringfireball.net/2010/07/improved_regex_for_matching_urls 関数は何も返さないので、理由がわかりません。

<?php
if ( false === function_exists('linkify') ):   
  function linkify($str) {
$pattern = '(?xi)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:\'".,<>?«»“”‘’]))';     
return preg_replace($pattern, "<a href=\"\\0\" rel=\"nofollow\" target=\"_blank\">\\0</a>", $str);      
}
endif;
?>

誰かが私がこれを機能させるのを手伝ってくれますか?ありがとう!

4

2 に答える 2

11

これを試して:

$pattern = '(?xi)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`\!()\[\]{};:\'".,<>?«»“”‘’]))';     
return preg_replace("!$pattern!i", "<a href=\"\\0\" rel=\"nofollow\" target=\"_blank\">\\0</a>", $str); 

PHPの関数には区切り文字pregが必要です。最後に、大文字と小文字を区別しませんi

アップデート

区切り文字として使用する場合は、元のパターン文字列を使用するため、パターン内で#エスケープする必要はありません(パターンには):!#"#$pattern#i"

アップデート2

リンクが正しいことを確認するには、次のようにします。

$pattern = '(?xi)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:\'".,<>?«»“”‘’]))';
return preg_replace_callback("#$pattern#i", function($matches) {
    $input = $matches[0];
    $url = preg_match('!^https?://!i', $input) ? $input : "http://$input";
    return '<a href="' . $url . '" rel="nofollow" target="_blank">' . "$input</a>";
}, $str); 

これはhttp://URLに追加されるため、ブラウザは相対リンクであるとは見なしません。

于 2012-04-03T22:18:33.083 に答える
3

上記のd_inevitableによる回答と同じ正規表現を使用して文字列からURLを取得することを検討していましたが、それらをリンクに変換したり、文字列の残りの部分を気にしたりすることは考えていませんでした。これは私がしたことです。それが役に立てば幸い。

/**
 * Returns the urls in an array from a string.
 * This dos NOT return the string, only the urls with-in.
 */
function get_urls($str){

    $regex = '(?xi)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:\'".,<>?«»“”‘’]))';
    preg_match_all("#$regex#i", $str, $matches);
    $urls = $matches[0];
    return $urls;

}
于 2014-09-08T02:30:02.183 に答える