PHP preg_matchのパターンを配列でやるには

予め検索したい文字列があって、ブログの記事のタイトルのように毎回変わるような文字列の場合での話です。

他にも使えますが簡単な例で言うと、NMB48の公式ブログ、あるいはSKEの選抜メンバーブログ(共にアメブロ)などのグループでやっているブログはテーマ別にそれぞれのメンバーが投稿します。その際に、記事一覧で誰の投稿かわかるように件名に名前を入れることが通常になっています。

もちろん名前を入れていない場合は検索が困難なのですが、記事の内容から探すという手もあります。

今回はわかりやすいように件名に名前(ニックネームあるいはpostネーム)が入っていると想定して解説します。

  • ブログのRSSを設定・取得して simplexml_load_file で配列に読み込みます。
  • 配列を foreach で展開してそれぞれのパラメーターを拾えるようにしておきます。
    • 必要なものとして件名、記事、日付、リンク等

これらを取得することで例えば $title にはそれぞれの記事の件名が入ります。
日付は、strtotime(日付) 等として好きなフォーマットに date で揃えれば良いと思います。

これで、 $dat[title] とすれば記事一覧が拾えるという感じです。

SKEの選抜メンバーアメブロで言うと、件名にはそれぞれのメンバーの名前かニックネーム等が入っています。それを配列にしておきます。配列はphp5.4からだったかarray()でくくらなくてもよくっているのでそれで書いてます。

後は取得したRSSの配列で見つけたいメンバーの名前と一致した場合に表示させればよいわけです。
その際に、例えば松井珠理奈の場合、「じゅりたん」といつも使用しているようなのでそれで検索します。この単語は他のメンバーとかぶること無くまた一般的な日本語にもほぼ出てこないので個人の記事と簡単に判別できます。
このメンバーの中では松井玲奈が曲者です。例えば件名に「はれなのでがんばります」とあった場合も松井玲奈の記事として拾ってしまいます。いつも公式のブログみたいに「(今日は?ω?今日。)」こういう感じで投稿してもらえるとそのパターンを作っておけばよいのですがアメブロの場合は、「れな(お誕・ω・生日)」みたいな感じで投稿していることが多いので「れな(」をパターンとしてやっていますが、「れなです」と言う感じの投稿もあるようなのでここらが難しい所。

こういう前置きをしておいてこのブログの件名にもなっているように配列でパターンを preg_match するにはどうすればよいかを書いてみたいと思います。これによっていくつかの名前の書き方があっても対応できるようになります。

まずそれに対応できるように関数を作っておきます。

2014/10/18 追記
※ preg_quoteの部分に間違いがあったので修正しました。コメントアウトしている箇所が修正前の部分です
元のままですとorに当たる | ←部分にもエスケープが入ってしまいパターンがマッチすることはありません。そのため配列をforeachで展開してそれぞれのキーワードにpreg_quoteを入れたものを$quortと言う変数に格納しています。こうすることでエスケープされたキーワードがimplodeによって|で結ばれると言う感じです。
(追記ここまで)

$pat = implode(“|”,$quort); の部分では、パターンを正規表現のorにあたる「|」で連結するようになっています。
つまり、松井玲奈の例で行くと 「れな|れな(」と$patに入ると言う意味合いです。

次に重要なのが、$quort[] = preg_quote($ptn); の preg_quote($ptn)この部分。
preg_quoteは正規表現で使えない記号、例えば”(“とか”*”みたいなものをバックスラッシュでエスケープしてくれる関数です。正規表現で使えない記号と書きましたが、今回だけです。投稿名に顔文字などを利用するメンバーの場合は必要になります。本来正規表現では「()」等はグループにまとめるなどの意味合いがあるので、今回の例の場合はそのままだと検索できなくてエラーが出ることになります。
例えば「れな(」とあった場合も、検索パターンに「)」が無いと言う意味合いのエラーが出ることでしょう。なのでpreg_quoteを利用して内部的には「れな\( (\はwordpress上で表示されないので全角になっています。半角の¥でもok)」となってないといけないわけです。

で、後は、条件があえばその内容を返すという関数になっています。ちなみに$needleの部分は $dat[‘title’]が飛んでいます。つまり、 pmatch($dat[‘title’] , $adt[‘word’]) と言う感じです。

データの作り方としては、

とこんな感じでどうでしょうか?
NMBやSKEのアメブロの場合、各メンバーがその日に何十件も投稿することはないので最大件数は不必要かも知れません。また $記事[] として表示部分の処理としましたが、ここも例えば outhtml みたいな別の関数を作っておいて outhtml($dat[‘titiel’] , $dat[‘link’], $dat[‘date’]) と言う感じで処理できるようにしておくと良いかも知れません。

リンクがわかっているわけですから、

簡単に言えばこんな感じ。すると $記事[] には返ってきたリンクが入っていくという感じです。
最終的には表示したい部分に、

などとできるという感じです。

Screenshot_from_2014-10-13 13:06:11ちなみにこのままでは使用していませんが、allabout48g(仮)では同じようなことで各メンバーのブログを取得しています。
ただ、それが原因でプロフィール詳細部分の左カラムの表示がちょっと遅いです(海外サーバーのためrss取得に時間がかかるのだと予想)。

スポンサーリンク

シェアする

フォローする