人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

PHPのパターンマッチ検索についてお聞きしたいのですが。
下記の構文を完成させるにはどうすればいいでしょうか。

<?PHP
$s="ag";
$data ="abcdgh";

//$sのなかの文字列が$dataに含まれていた場合
//if文を実行させたいのです。
//$sの中が(bとh)(cd)であっても動作可能な様に。

if (/*$dataの中に$sの文字列が含まれていた場合*/) {
//$dataはaとgが含まれているので実行。
echo "できた!!!";
}
?>

初心者のためわかり易い回答がありがたいです。

●質問者: hanabusatsukasa
●カテゴリ:コンピュータ ウェブ制作
✍キーワード:CD echo PHP パターン マッチ
○ 状態 :終了
└ 回答数 : 4/4件

▽最新の回答へ

1 ● mzk
●30ポイント

if(false != strpos($data,$s)){

echo "できた!!!";

}

strposは文字列検索をしますけど、見つからなかったときはfalseを返します。

ならfalseじゃない場合は見つかったということなので、このやり方で動作をすると思います。

http://php.s3.to/man/function.strpos.html

◎質問者からの返答

ありがとうございました。


2 ● tobeoscontinue
●31ポイント
<?php
function match($s, $a)
{
 $offset= 0;
 for ($i= 0; $i < strlen($s); $i++) {
 $offset = stripos($a, $s[$i], $offset);// PHP5
 if ($offset === FALSE) return FALSE;
 $offset++;
 }
 return TRUE;
}
//検索文字列
$s="ag";
//検索したい変数
$a="cdegh";
$b="cdeh";
$c="chi";
$d="abcdefgh";

if (match($s, $a)) echo $a."<br>";
if (match($s, $b)) echo $b."<br>";
if (match($s, $c)) echo $c."<br>";
if (match($s, $d)) echo $d."<br>";

?>

条件を充たす関数を探してみたのですが見つけることができず(無知なだけ)作って見ました(車輪の再発明?)

$sが文字列でなく正規表現が使えるのであれば関数はあるのですが。

$sはascii文字列とします。sjis,euc,utf-8などの日本語文字の場合はまた使う関数が別なので。

strlen($s)は$sの文字数(バイト数)、"ag"なら2となります。

forは繰り返しです。

$s[$i]で$iは0,1,2と変化するので$sの文字列から順に'a','g'を取り出すことになります。

http://php.s3.to/man/function.stripos.html]

stripos($a, $s[$i], $offset))は文字列$aの$offsetの位置から$s[$i]の文字があるか調べて見つかればその位置を返します。striposは大文字、小文字の区別をしませんが使えるのはPHP5です。PHP4ではstrposになりますがこちらは区別します。つまり'a'と'A'は違うものとなります。

見つからない場合、FALSEが返ります。ここで重要なことは===を使うことです。==だと先頭位置0を返した時にも反応してしまいます。


striposでFALSEが返るということは$sの中の文字が$aの中に無いということなのでこれ以上続ける意味がないのでそくreturnします。


見つかった場合は次の位置から探すために$offsetを一つすすめています。


forをぬけるということは$sの全ての文字が$aの中にあるということなのでTRUEを返します

◎質問者からの返答

一度読んだだけではまだ難しいです。

何度か自分でやってみたいと思います。

ありがとうございました。


3 ● Mook
●33ポイント

"ag" が $data の中にあるといった条件では、strpos では、$data が "abcdefgh" の場 False になります。

'a' と 'g' が離れているため。


正規表現を使用した場合

 $data = "abcdefgh";
 if ( ereg( ".*a.*g", $data ) == true ) {
 echo "できた!!!";
 }
 echo "できた!!!";
}

は、true になりますが、$data が "hgdcba" の場合、false になります。

これは、'a' と 'g' の順番が異なるからです。


順番が逆でもtrue としたい場合は、

 $data = "abcdefgh";
 if ( ( ereg( ".*a.*g", $data ) || ereg( ".*g.*a", $data ) ) == true ) {
 echo "できた!!!";
 }
 $data = "hgdcba";
 if ( ( ereg( ".*a.*g", $data ) || ereg( ".*g.*a", $data ) ) == true ) {
 echo "できた!!!";
 }

とします。

しかし、$s の中の文字が順序によらずすべてある場合を判定したいのなら、$sが 3文字以上あるような場合を考えると、下記のような関数を作成した方が早いでしょう。

// 自分で定義した関数 myFind
<?
function myFind( $myFind, $data ) {
 for( $i=1 ; $i<=strlen( $myFind ), $i++ ) { // 1文字ずつ検索
 if ( ereg( substr( $myFind, $i, 1 ), $data ) == false ) {
 return false; // 1文字でも見つからなかったら false
 }
 }
 return true; // すべて見つかったら true
}

 $data = "abcdefgh";
 if ( myFind( "adh", $data ) == true ) {
 echo "できた!!!";
 }
?>

PHP ereg

PHP substr

◎質問者からの返答

何度か試して自分のものにしたいとおもいます。

ありがとうございます。


4 ● Mook
●0ポイント

こちらは、ポイント不要です。

ちょっとぼけていましたので、訂正。

if ( ( ereg( ".*a.*g", $data ) || ereg( ".*g.*a", $data ) ) == TRUE ) {
} 

でも動くかもしれませんが、

if ( ereg( ".*a.*g", $data )|| ereg( ".*g.*a", $data ) {
}

の方が良いですね。

また、TRUE、FALSE は大文字で書くべきでした。

(WSH の悪影響がでてしまった・・・)

PHP 論理型

◎質問者からの返答

いえいえ、ありがとうございます。

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ