![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?8acaa2e)
いつもお世話になっております。
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に該当する場合になってくると速度もかなり遅く感じます。
どうにかもう少し高速化したいなあと考えているのですが、何か良い方法はありますでしょうか?
よろしくお願い致します。
![](http://oshiete.xgoo.jp/images/v2/common/profile/M/noimageicon_setting_15.png?8acaa2e)
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で質問しましょう!
似たような質問が見つかりました
- JavaScript switch文のswitch(n)の部分を複数の値にするか、if文に変えてほしいです。 1 2022/07/27 17:18
- JavaScript jsで、switch文で書かれた分をif文にできませんか。 1 2022/07/28 15:10
- その他(自然科学) 科学 哲学 について 4 2022/09/20 00:19
- オープンソース ChatGPTをスプレッドシートと連携して自動でリサーチしたいんですがうまく出来ません。。。 1 2023/05/05 15:59
- JavaScript セレクトボックスを2つ設けて選択して初めてメッセを表示 1 2022/07/27 12:15
- ライフスタイル・ヘルスケア URLを開くアプリが見つかりません 2 2022/09/16 12:09
- 大学受験 本気で困ってます! 大学受験/現代文の参考書ルートについて質問です! 現代文の参考書ルートについてで 2 2023/08/13 20:07
- JavaScript セレクトボックスを2つ選択してメッセージなどを表示するには。~運賃検索プログラムを完成させたい~ 1 2022/07/22 11:10
- Excel(エクセル) セルの値をグーグルで検索するエクセルVBAについて! 2 2022/08/01 21:41
- Amazon アマゾンで出版中の本の販売部数を伸ばすためには、どうすれば良いですか? 4 2022/08/18 23:30
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
preg_matchでエラーが出ます。
-
Excelで数字のみを2倍3倍にする...
-
PHP 文字の出現回数2
-
PHPメールフォーム URLと半角...
-
PHP4.4.8でxmlを表示する方法
-
A~Z、0~9を指定する方法
-
、"(ダブルクォーテーション)...
-
正規表現で「0」のみ抽出
-
preg_match関数で4-16桁の英数...
-
VBAを使ってHTMLソースから特定...
-
mb_ereg_matchのつかいかたにつ...
-
preg_matchで指定ファイルのタ...
-
VBAのコマンドボタンの文字列の...
-
ソースコードの1行が長いとき...
-
文字の入力で横バー上段、中断...
-
COBOLの改行
-
エスケープ文字の復帰(¥r)と...
-
改行コード(CR/LF)の設...
-
全角括弧と全角読点の間隔を狭...
-
ダブルコーテーション(
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
、"(ダブルクォーテーション)...
-
VBAを使ってHTMLソースから特定...
-
PHPで変数から1行目だけを取得...
-
Excelで数字のみを2倍3倍にする...
-
preg_matchでエラーが出ます。
-
正規表現でシングルクォーテー...
-
URLを抽出する正規表現
-
正規表現パターンの記入方法に...
-
PHPで<a>タグ内からURLと文字を...
-
PHP 複数行の正規表現
-
PHPの正規表現で住所を分けるに...
-
電話番号のチェック ハイフン...
-
正規表現で「0」のみ抽出
-
ereg_match関数について
-
preg_matchで Warning: Undefin...
-
PHPメールフォーム URLと半角...
-
正規表現で特定のHTMLタグのク...
-
preg_matchで指定ファイルのタ...
-
変数に指定文字列が含まれると...
-
C#でのワイルドカードを使った...
おすすめ情報