PHPで自動キーワードリンク

別に運営しているサイトで、用語集なんてコンテンツがあります。最近、自動キーワードリンク機能がほしくなって探したら正規表現で簡単にできそうなので、作ってみました。今回はそのメモ。

このエントリーでは『JavaとJavaScriptは名前は似てるけど、違うプログラミング言語だよ』という文章と『Java』『JavaScript』『プログラミング言語』の3つが入った配列を用意して、Wikipediaのページにリンクするということをやってみます。

ソースコード

<?php
$str = "JavaとJavaScriptは名前は似てるけど、違うプログラミング言語だよ";
$list = array('Java', 'JavaScript', 'プログラミング言語');

$reg = '/(';
foreach($list as $value){
	if($reg !== '/(') $reg .= '|';
	$reg .= $value;
}
$reg .= ')/';

$str = preg_replace($reg,'<a href="http://ja.wikipedia.org/wiki/$1">$1</a>', $str);

echo $str;
?>

簡単に解説をしておくと、5~10行目で、正規表現用の変数を作ってます。|がORの意味で、8行目で$listの中を一つずついれていってます。
 12行目で置換してます。$1はかっこ()内の正規表現結果をあらわしてます。実行結果は以下です。

実行結果

$1‘, $str); //$listのどれかがあれば置換

echo $str;
?>

うーん。『JavaSceipt』の部分が『JavaScript』ではなく『Java』で認識しちゃってます。どうやら、同じ位置から始まった単語では、正規表現の|の区分けにおいてはじめのほうにある単語が優先されちゃうそうです。
 というわけで、$listを文字列の長い順に並べ替えてから$regを作ることにしましょう。ここではPHPのユーザー定義でソートできるusort関数を使うことにします。

ソースコード

<?php
$str = "JavaとJavaScriptは名前は似てるけど、違うプログラミング言語だよ";
$list = array('Java', 'JavaScript', 'プログラミング言語');

function cmp($a, $b)
{
	return strlen($b) - strlen($a);
}

usort($list, "cmp");

$reg = '/(';
foreach($list as $value){
	if($reg !== '/(') $reg .= '|';
	$reg .= $value;
}
$reg .= ')/';

$str = preg_replace($reg,'<a href="http://ja.wikipedia.org/wiki/$1">$1</a>', $str);

echo $str;
?>

5行目から8行目でソート用の関数を作って、usortの第二引数でその関数の名前を渡しています。

実行結果

$1‘, $str);

echo $str;
?>

うん。うまくいった。

ところで、これでうまくいってはいるんですが、URLエンコードをしたほうがもっといいような気がします(というより、自分が作ったサイトは、URLエンコードしないとIEでは、ちゃんと動いてくれなかった)。
 URLエンコードは、19行目の下に以下のコードを追加したら動くはずです。

$str = preg_replace('/\/wiki\/(.*?)">/e','\'/wiki/\'.urlencode("$1").\'">\'',$str);

これが一番自分でもよく分からなかったとこ。下記のページを参考にしました。
参照を使ったリンクをurlエンコードする方法 – PHPプロ!Q&A掲示板

というわけで実行結果

実行結果

$1‘, $str);
$str = preg_replace(‘/ja.wikipedia.org\/wiki\/(.*?)”>/e’,’\’ja.wikipedia.org/wiki/\’.urlencode(“$1″).\'”>\”,$str);

echo $str;
?>

コメント

タイトルとURLをコピーしました