PHPのパターンマッチ検索についてお聞きしたいのですが。

下記の構文を完成させるにはどうすればいいでしょうか。

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

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

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

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

回答の条件
  • URL必須
  • 1人2回まで
  • 登録:2006/10/08 02:43:37
  • 終了:2006/10/08 20:07:54

回答(4件)

id:kazu1107 No.1

kazu1107回答回数199ベストアンサー獲得回数142006/10/08 06:51:55

ポイント30pt

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

echo "できた!!!";

}

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

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

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

id:hanabusatsukasa

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

2006/10/08 17:58:56
id:tobeoscontinue No.2

tobeoscontinue回答回数214ベストアンサー獲得回数542006/10/08 12:50:28

ポイント31pt
<?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を返します

id:hanabusatsukasa

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

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

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

2006/10/08 17:58:53
id:Mook No.3

Mook回答回数1312ベストアンサー獲得回数3912006/10/08 14:02:37

ポイント33pt

"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

id:hanabusatsukasa

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

ありがとうございます。

2006/10/08 18:00:43
id:Mook No.4

Mook回答回数1312ベストアンサー獲得回数3912006/10/08 14:30:40

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

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

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

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

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

の方が良いですね。

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

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

PHP 論理型

id:hanabusatsukasa

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

2006/10/08 17:59:24
  • id:Mook
    うーん、まだボケが残ってた・・・。
    ".*a.*g" は "a.*g"で十分でした。

    希望する結果が、$s の記述順に依存するのかしないのかで、やり方が変わりますが、依存するのであれば、ereg だけでいけると思います。

    順序に依存せず、すべての文字が存在する場合、目的の条件を判断する関数が早いと思います。

    正規表現を理解すると、いろいろなやり方ができるようになるかと思います。

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

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

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

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