URLの正規表現とpreg_replace_callback関数について
今はphpを使って開発しているんだけど相変わらず正規表現につまずく。
後、Javaに慣れてしまっているんで相変わらずphpの標準関数とかにもつまずく。
というわけで備忘録として書いてみました。
まずはURLの正規表現についてですが、
何をしたかったかというとテキスト本文中にURLがあるとリンクにしたかった訳です。
どういうことかと言うと、、、
ヤホーでぐぐれ。 http://www.google.co.jp 分かったか。
これを、、
ヤホーでぐぐれ。 http://www.google.co.jp 分かったか。
というようにしたいわけです。
まずはURLを正規表現で抽出する方法ですが、どっかからのサイトのパクリです。
/https?:\/\/[-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#]+/i
先頭と最後に/がついてますが、他の言語だと違った筈なので適宜読み替えて下さい。
これで本文中にあるURLを抽出できます。
更にもう一歩進んでこんな表記がされていた場合、
ヤホーでぐぐれ。 www.google.co.jp 分かったか。
とhttp://が省かれていますが、これも先ほどと同じく、
ヤホーでぐぐれ。 www.google.co.jp 分かったか。
とリンクにしたい場合、
先ほどの正規表現に対して更に条件を加えます。
/https?:\/\/[-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#]+|w{3}[.][-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#]+/i
これで先ずは本文中にURL表記されいてる箇所を抽出できるようになりました。
本来ならwwwがついてないURLに対しても抽出したかったんだけど、
今回はそこまでする必要がなかったので断念します。
後は、http://やwwwから始まったらその後に半角英数が続くまでURLの抽出条件にされてしまうのでその考慮も今後は必要かなと。
じゃあ次にURL部分をリンクにする方法ですが、
簡単な方法は該当する箇所があればaタグに置き換えるという方法です。
じゃあ早速やってみましょう。
一番簡単なやり方はpreg_replace関数を利用するという方法です。
説明がめんどくさいのでソース載せます。
class StringUtils { public function urlRegex($str) { $pattern = "/https?:\/\/[-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#]+|w{3}[.][-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#]+/i"; $replacement = '<a href="\0" target="_blank">\0</a>'; $strText = preg_replace($pattern, $replacement, $str); return $strText; } }
じゃあ早速
class StringUtils { public function urlRegex($str) { $pattern = "/https?:\/\/[-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#]+|w{3}[.][-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#]+/i"; $strText = preg_replace_callback($pattern, 'replace', $str); return $strText; } public function replace($matches) { 〜 〜 } }
と修正していざ実行してみると、、、、
Warning: preg_replace_callback(): Requires argument 2, 'replace', to be a valid callback
というエラーが発生してしまいました。
なぜだ、どこも間違っていないのに、、、と悩んでいたのですがどうやら
preg_replace_callbackの関数の呼び出し方法がまずかったみたいです。
という事で修正したのがこちら、、、
class StringUtils { public function urlRegex($str) { $pattern = "/https?:\/\/[-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#]+|w{3}[.][-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#]+/i"; $strText = preg_replace_callback($pattern, array(get_class($this), 'replace'), $str); return $strText; } public function replace($matches) { 〜 〜 } }
関数を呼び出すときは
array(get_class($this), 'replace')
と書かないと駄目みたいです。詳しい説明は省きますがclassを使っている時はこう書きます。
以上でwwwから始まるURLも無事に変換出来ました。
いやぁ良かった良かった。
間違いがあればコメントくだせぇ。