phpについての質問です。


APIからキーワードをひっぱってきて、
NGワードがあると表示しない・・というものを作っています。

NGワードを配列にして・・
$ngword = explode(",", "ダメ,NG,禁止・・

whileで回して1つ1つifとstrstrで判定しています。
if (strstr($apiword, $ngword[$a])!=""){・・

で、なんか無駄に時間がかかっているような気がします。
もっと軽くするにはどうすればいいですか?

回答の条件
  • 1人2回まで
  • 登録:2008/10/01 20:05:42
  • 終了:2008/10/08 20:10:02

回答(3件)

id:m_nagase No.1

nagase回答回数58ベストアンサー獲得回数82008/10/01 23:09:19

ポイント27pt

正規表現を使う方法が考えられます。

http://www.php.net/manual/ja/book.pcre.php

NGワードを選択子メタ文字 "|" でつないだ以下のような正規表現パターンを作り、対象となるキーワードとマッチさせれば良いのです。

/NGワード1|NGワード2|NGワード3/  // "NGワード1" または "NGワード2" または "NGワード3" どれかに一致する

簡単に書くと

$ngpattern="";
for($i=0;$i<count($ngword);$i++){
  if($i>0){ $ngpattern.="|"; }
  $ngpattern.=$ngword[$i];
}
$f=preg_match("/".$ngpattern."/",$apiword);
// $apiwordにNGワードのどれかが含まれていれば $fは1 含まれていなければ $fは0 となる

ただしNGワードに正規表現のメタ文字が含まれている場合は、正規表現パターンを生成するときに適切にエスケープしなければなりません。

http://www.php.net/manual/ja/regexp.reference.php

id:unau No.2

ゆーの回答回数7ベストアンサー獲得回数02008/10/02 00:31:58

ポイント27pt

$apiword に絶対含まれない文字をデリミタにした $ngword_list を作り、それと比較するのはどうでしょう。

たとえば、"\r" が絶対含まれないのであれば、

$ngword_list = "ダメ\rNG\r禁止\r...";

として、$apiword が存在するか比較するとか。

この方法は簡単ではありますが、線形で探すのであまり速くありません。

NG ワードを探すのが前方一致や後方一致に限られるのであれば簡単な速い検索方法があるかもしれません。

部分一致が必要なのであれば、高速化には全文検索ライブラリが必要になってくるかと思います。

id:hard No.3

hard回答回数32ベストアンサー獲得回数42008/10/02 11:47:49

ポイント26pt

まず、現在のコードでの問題点を考えてみました。

  • 配列を回すのにwhile()を使用する必要性が感じられないので、foreach()を使用する
  • strstr()よりstrpos()の比較の方が早い

の2点を加えたコードをつくってみました。

$ngword = explode(",", "ダメ,NG,禁止");

foreach ($ngword as $word){
	if (strpos($word, $apiword) !== false){
		// 表示しない処理をして終了
		break;
	}
}

もし、これで速度に大差がないようであれば、正規表現を使ったやり方もあります。

『,』で区切るのではなく『|』で区切った文字列で検索します。

$strword = "ダメ|NG|禁止";

if (preg_match("[" . quotemeta($strword) . "]", $apiword)){
	// 表示しない処理
}

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません