PHP:#thNbvhr
返信数:0件(解決済み - Twihelpmeにて返信を締め切りました)2231 view

w3gjp- URLをリンクに置き換えながら自サイトと他サイトで処理をわける正規表現(こんなときにも言明が便利)
Twitterのハッシュタグとアカウント名(スクリーンネーム)をリンクに置き換える正規表現( #thhyu35 参照)と同じ正規表現の言明サブパターンを用いたネタです。今回は、http://〜 の一連のURLを構成する文字列をリンクに置き換える場合の正規表現について紹介します。
ユーザからのデータ入力を受け付けるシステムであれば、http://〜 のURLを構成する文字列をリンクに置き換えたりすることは少なくないはずです。また、自サイト内のURLが貼付けられた場合と他サイトのURLが貼付けられた場合とで、ただリンクに置換するだけでなく、他サイトには target="_blank" や rel="nofollw" を付けたいなど、処理を別けたいという場合も少なくないかと思います。
大概は if文に preg_match関数等を用いて、自サイトのドメインのパターンにマッチするかしないかで、マッチしなかった else の方に target="_blank" や rel="nofollow" を付けるというのが一般的に多い作法かと思いますが、こんなときにも言明のサブパターンを使えば簡便な繰り返しだけの記述で済みます。
$test という変数にユーザから受け付けたデータが入ってるとして、一応、HTTPとHTTPSの2つのプロトコルをサポートした場合は
このように2つ続けて書くだけで、if文などを使う必要もありません。もちろん twihelp.me とある部分を自分のサイトのドメインに変えてもらう必要はありますが、一つずつ順を追って解説していきましょう。//自サイト以外(他サイト)のURLの場合 $test = preg_replace("/(https?:\/\/)(?!twihelp.me)([-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)/", "<a href=\"\\1\\2\" target=\"_blank\" rel=\"nofollow\">\\1\\2</a>", $test); //自サイトのURLの場合 $test = preg_replace("/(https?:\/\/twihelp.me)([-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)/", "<a href=\"\\2\">\\1\\2</a>", $test);- まず、(https?:\/\/) は、http:// と https:// のHTTPとHTTPSの2つのプロトコルをサポートした記述です。shttp:// のSHTTPプロトコルもサポートするのであれば、(s?https?:\/\/) と記述します。
- 続いて、(?!twihelp.me) が今回のポイントです。(? の部分が先読み言明で、(?= だと肯定、(?! だと否定を意味します。ここでは (?! を使っているので先読み言明の否定を意味します。これで twihelp.me があるURLにはマッチしないことになります。つまり、http://twihelp.me のつくURLについては次の2つ目の正規表現の方でマッチすることになります。
- ([-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#]+) は、ハイフン「-」、アンダーバー「_」、ドット「.」、エクスクラメーションマーク「!」、チルダ「~」、アスタリスク「*」、シングルクォーテション「'」、左小括弧「(」、右小括弧「 )」、小文字アルファベット「a-z」、大文字アルファベット「A-Z」、数字「0-9」、セミコロン「;」、スラッシュ「/」、クエスチョンマーク「?」、コロン「:」、アットマーク「@」、アンパサド「&」、イコール「=」、プラス「+」、ドルマーク「$」、カンマ「,」、パーセント「%」、ハッシュ「#」を一連の文字クラスとして、+があるのでこれらのいずれかの文字が1回以上続くパターンにマッチするという意味です。
- 2つ目の方の正規表現が自サイトのみにマッチする方で、(https?:\/\/twihelp.me) とあるように、http://twihelp.me か https://twihelp.me 始まりの以降に先の一連の文字クラスが一文字以上ある文字列にマッチします。
http://www.din.or.jp/~ohzaki/perl.htm#httpURL
w3gjpさんの投稿に1人が「いいね!」と言っています。
