
いつもお世話になっております。
phpにて、文中にキーワードがあるかどうか判定し、そのキーワードによって処理を変えていくというプログラムを作成しています。
preg_matchまたはstrposによるキーワード判定と、switchによる処理を組み合わせたものです。
//判定対象となる文章
$text = "判定対象となる文章";
//判定キーワードの設定
$word1 = "/キーワード1|きーわーど1|keyword1/";
$word2 = "/キーワード2|きーわーど2|keyword2/";
.
.(中略)
.
$word30 = "/キーワード30|きーわーど30|keyword30/";
//判定処理
switch (true) {
case preg_match($word1, $text):
echo "キーワード1に該当します"
break;
case preg_match($word2, $text):
echo "キーワード2に該当します"
break;
.
.(大量のcase)
.
case preg_match($word30, $text) && preg_match($word1, $text):
echo "キーワード1かつキーワード30に該当します"
break;
};
ざっと書くとこのような構造になっています。
しかしキーワード分岐がかなり多岐に渡っている状態で、switch文の後半のcaseに該当する場合になってくると速度もかなり遅く感じます。
どうにかもう少し高速化したいなあと考えているのですが、何か良い方法はありますでしょうか?
よろしくお願い致します。

No.2ベストアンサー
- 回答日時:
一個のswitch文だと、最初のcaseで、"キーワード1" にマッチすると、ループを抜けるので、もし"キーワード30"も同時に含まれていたとしても、最後の"キーワード1かつキーワード30" は、実行されないと思います。
キーワードを全部patternに放り込めばいいのでは?と最初思ったのだけど、キーワードのグループ分けをしたいのかと推測。
グループ分け用にhash配列を作成してpreg_match_allを使ってみた
<?php
$text = 'キー3判定きー1対象となるけーkey3文章key4';
/* グループ分け用hash配列 キーにkeyword文字列, 値にグループ番号 */
$keyhash = array( 'key1'=>1, 'きー1'=>1, 'キー1'=>1
, 'key2'=>2, 'きー2'=>2, 'キー2'=>2
, 'key3'=>3, 'きー3'=>3, 'キー3'=>3
, 'key4'=>4, 'きー4'=>4, 'キー4'=>4
);
$pattern = '/('. implode( '|' , array_keys($keyhash)) .')/';
$n = preg_match_all($pattern , $text, $matches, PREG_OFFSET_CAPTURE);
echo "<pre>: text : $text\n: pattern : $pattern\n: matches : ";
var_dump($matches);
echo '</pre>';
$match_group = array();
if( $n>0){
echo "\n<dl>";
for( $i=0; $i<$n; $i++){
echo "<dt>match $i :</dt><dd>keyword : {$matches[0][$i][0]}
, 文字列のオフセット {$matches[0][$i][1]}, group {$keyhash[ $matches[0][$i][0]]}</dd>";
/* $keyhash[ $matches[0][$i][0] ] でマッチしたグループ番号がわかるので適宜処理分岐する */
$g = $keyhash[ $matches[0][$i][0]];
if(isset( $match_group[$g] )) {
$match_group[$g] ++;
}else{
$match_group[$g] = 1;
}
}
echo "</dl>\n";
}else{
echo '一個もマッチしませんでした';
}
echo '<pre>match group list : ';
var_dump($match_group);
echo '</pre>';
?>
お礼が大変遅くなりまして申し訳ありませんでした。
回答頂いたコードを応用し、無事目的のものを作成することができました!
ありがとうございました。
No.3
- 回答日時:
そういえば、COBOLやCやVBなどコンパイラでもスイッチ文に匹敵する構文が遅くなると使用禁止になったことあります。
そんなに凝って難しく作らないで、単純にIF文にしてしまったら良くないですか?
IF文をネストとする必要はありません。
メッセージは文字列結合して積み上げたり、メッセージが出た回数をカウントしたら良いし。
どうせ、判定はしなくちゃ駄目なのなら、ストレートなIF文が良いと思います。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
preg_matchの正規表現で
-
PHPで<a>タグ内からURLと文字を...
-
preg_matchでエラーが出ます。
-
正規表現で特定のHTMLタグのク...
-
正規表現パターンの記入方法に...
-
PHPの「ereg」って何の略で...
-
Excelで数字のみを2倍3倍にする...
-
preg_matchでのマッチが正しく...
-
VBAを使ってHTMLソースから特定...
-
\\bとはなんでしょうか?
-
http://とhttps://のどちらでも...
-
PHPメールフォーム URLと半角...
-
HTMLファイルからCSSファイル名...
-
正規表現でシングルクォーテー...
-
phpで文字列に"や'などが含まれ...
-
正規表現で「0」のみ抽出
-
正規表現を用いてHTML内の文字...
-
ここで「文字列連結演算子」が...
-
漢字を含んだ正規表現
-
PHPで変数から1行目だけを取得...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Excelで数字のみを2倍3倍にする...
-
、"(ダブルクォーテーション)...
-
PHPの「ereg」って何の略で...
-
Smartyで部分一致
-
preg_matchでエラーが出ます。
-
HTMLファイルからCSSファイル名...
-
http://とhttps://のどちらでも...
-
phpで文字列に"や'などが含まれ...
-
正規表現で「0」のみ抽出
-
VBAを使ってHTMLソースから特定...
-
PHPで変数から1行目だけを取得...
-
ここで「文字列連結演算子」が...
-
\\bとはなんでしょうか?
-
正規表現でシングルクォーテー...
-
preg_matchでのマッチが正しく...
-
PHPで<a>タグ内からURLと文字を...
-
PHPメールフォーム URLと半角...
-
漢字を含んだ正規表現
-
preg_matchの検索について
-
PHPで あるフォルダ内の、特定...
おすすめ情報