PHPの正規表現 メール受信と文字コードについて

このQ&Aのポイント
  • PHPの正規表現を使用してYahooのメールサーバからメールを取得し、特定の語句が含まれているか調べたい。
  • メール本文の文字コードがSJISであるため、正規表現のマッチングに問題がある。
  • 問題の解決策として、SJISの代わりに別の文字コードを使用するか、メール本文を変換する方法がある。
回答を見る
  • ベストアンサー

PHPの正規表現 メール受信と文字コードについて

Yahooのメールサーバに接続しメールを取得、メール本文に特定の語句が含まれているか調べたいのですが、うまく行かず悩んでいます。 SJIS文字コードが原因なんでしょうか? かなり長い文章になるので、お暇でしたらご教授下さい。 PHP Version 5.2.5です。 以下のプログラムでの問題点です。 <?php $mb=imap_open("{pop.mail.yahoo.co.jp:110/pop3}INBOX","ID","pass") or die("メールボックスを開けません<br>"); $i=4;//メール番号 //imap_fetchbody、mb_convert_encodingで取得した変数<$body_sjis>と比較する為、メール本文を変数<$mail_honbun>としてファイル内に定義。 $mail_honbun="次のことはを感じで、書きなさい。(すべて)手へんの漢字です。 「正解」はこのあとすぐ。仕上げの湾カールが決まるのは:エッセンシャルダメージケア新発売"; $body=imap_fetchbody($mb,$i,1,FT_PEEK);//本文取得 $body_sjis=mb_convert_encoding($body,"SJIS","auto");//SJISに変換 echo("$body_sjis<br><br><br>"); echo("[mail_honbunの場合]<br>"); if(preg_match("/次の.+書きなさい。/",$mail_honbun,$temp))//OK echo("$temp[0]<br>"); else echo("NOT MATCH<br>"); if(preg_match("/次の.+正解/",$mail_honbun,$temp))//OK echo("$temp[0]<br>"); else echo("NOT MATCH<br>"); if(preg_match("/エッセンシャル/",$mail_honbun,$temp))//OK echo("$temp[0]<br>"); else echo("NOT MATCH<br>"); if(preg_match("/ダメージ/",$mail_honbun,$temp))//NG 何故ダメージはマッチしない? echo("$temp[0]<br>"); else echo("NOT MATCH<br>"); echo("---------------------------------------<br>"); echo("[body_sjisの場合]<br>"); if(preg_match("/次の.+書きなさい。/",$body_sjis,$temp))//OK echo("$temp[0]<br>"); else echo("NOT MATCH<br>"); if(preg_match("/書き.+正解/",$body_sjis,$temp))//NG 。を超えるとマッチしない echo("$temp[0]<br>"); else echo("NOT MATCH<br>"); if(preg_match("/エッセンシャル/",$body_sjis,$temp))//OK エッセンシャルはOK echo("$temp[0]<br>"); else echo("NOT MATCH<br>"); if(preg_match("/ダメージ/",$body_sjis,$temp))//NG ダメージがNG、何故? echo("$temp[0]<br>"); else echo("NOT MATCH<br>"); ?> ## 結果 ######################################################## [mail_honbunの場合] 次のことはを感じで、書きなさい。 次のことはを感じで、書きなさい。(すべて)手へんの漢字です。 「正解 エッセンシャル NOT MATCH --------------------------------------- [body_sjisの場合] 次のことはを感じで、書きなさい。 NOT MATCH エッセンシャル NOT MATCH ################################################################# 問題点<$mail_honbun>の場合 マッチするカタカナと、しないカタカナがある事。(エッセンシャルがマッチして、ダメージがマッチしない事) 問題点<$body_sjis>の場合 。を超えるとマッチしない事。 マッチするカタカナと、しないカタカナがある事。(エッセンシャルがマッチして、ダメージがマッチしない事) 自分で何が問題なのか、何を知らないのかがはっきりしません。 文字コードSJISを使わない方がいいのでしょうか? 参考になる事や、調べたら解決しそうなキーワードがあれば教えて下さい。宜しくお願いします。 ファイル"php.ini"の設定 mbstring.language = Japanese mbstring.internal_encoding = SJIS mbstring.http_input = auto mbstring.http_output = SJIS mbstring.encoding_translation = On mbstring.detect_order = SJIS,EUC-JP,JIS,UTF-8,ASCII

  • PHP
  • 回答数1
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.1

preg_matchはShiftJISやECU-JPには対応していません。 UTF-8ならば、複数バイトからなる文字を正しく認識します。 mbstring.language = Japanese mbstring.internal_encoding = SJIS mbstring.http_input = auto mbstring.http_output = SJIS mbstring.encoding_translation = On mbstring.detect_order = SJIS,EUC-JP,JIS,UTF-8,ASCII この辺の設定は、preg_* にはまったく影響しません。 参照しないから。 mb_ereg* を使うにしても設定するのはここじゃないような。

narusuji
質問者

お礼

ありがとうございます。 preg_matchがSJISに対応していない事すら知りませんでした。 UTF-8でもいいんですが、SJISの文字列を扱ってみたいので、もう少し調べてみたいと思います。

narusuji
質問者

補足

preg_matchではなく、mb_ereg()を使ったら上手くいきました。 if(mb_ereg("文字列",$body_sjis,$match)) echo("$match[0]<br>");

関連するQ&A

  • 全角カタカナの正規表現

    if (preg_match('/[ァ-ヶー]+/', $value, $match )) { print ("$value"."はカタカナです。"."($match[0])"."<br />") } else { print ("$value"."はカタカナではない。<br />"); } という感じで全角カタカナにマッチさせる正規表現を使いたいのですが、このやり方だと「全角カタカナを含んでいる…」という表現になってしまいます。ある文字列が「すべて全角カタカナである」という正規表現を考えているのですが、なかなかうまくいきません。逆引きのサンプルなんかでもなかなか見つからなくて困っています。  同様に「すべて平仮名にマッチ!」というのにも応用できると思うのですが、なかなかうまく行きません。  是非、そのやり方やヒントをおしえてください。  マルチバイト対応なので[ぁ-ん]のような形で表記できます。またPerl互換(preg_match)で作っているので、Perlに詳しい方も是非是非おしえてください。

    • ベストアンサー
    • PHP
  • 正規表現について

    PHP5.2.4を使用しています。 任意の数の引数がある文字列をpreg_matchを使ってマッチさせたいのですが、 例えば"ENUM(ab,cd)"は ab と cd の2つの引数があるとします。 次のようなパターン文字列まではアイデアとして浮かんだのですが、 引数の最後は , がないので当然ですがマッチしません・・・ どのようにパターン文字列を記述すれば良いのでしょうか? $str = "ENUM(ab,cd)"; if (preg_match("/ENUM\(([^\,]+\,)+\)/", $str, $match)) { print "{$match[0]}<br>\n"; }

    • 締切済み
    • PHP
  • 正規表現で切り出せません。 < と > の間?

    宜しくお願いいたします。 PHP5.1.6です。 メールの受信をするときにメールアドレスだけを切り出したいのですが うまく出来ません。 【例-1】の様に、すると < > の間が表示するのですが 【例-2】の例のように、変数を入れると何も表示しません。 【例-1】で使用した文字列は、【例-2】の$from を echo で表示させたものをコピーしています どのようにしたらいいでしょうか? 宜しくお願いいたします。 【例-1】 $test="教えてお名前 <****@*******.com>"; $pattern = "<(.*)>"; if (preg_match( "/".$pattern."/i", $test, $match ) ){ //$from0 = $match[0]; $from1 = $match[1]; //echo $from0; echo $from1; } これで、うまく echo $from1 でメールアドレスだけ表示してくれます。 *** なぜか、$from0 には元の文字列は表示しませんが。 置き換える元の文字列を下記変数に変えると表示しません。 【例-2】 $mboxes = imap_check($mbox); $head = imap_header($mbox, $i); $from = htmlspecialchars(mb_decode_mimeheader($head->fromaddress)); $pattern = "<(.*)>"; if (preg_match( "/".$pattern."/i", "$from", $match ) ){ //$from0 = $match[0]; $from1 = $match[1]; //echo $from0; echo $from1; } **$from の所は "" で囲んだり、外したりしましたが一緒でした。

    • ベストアンサー
    • PHP
  • 正規表現で記号 & アンドの検索ってサポートされてない?

    preg_matchあるいはereg関数を用いて、 &p=XX (XXは半角数字2桁)のようなパラメーターがURLに含まれるかを調べたいのですが、p=XXまではうまくいくのですが、&p=XXだと マッチしなくなります。 $url = "http://hogehoge.jp/index.php&p=01"; $pattern = "&p=[0-9]{2}"; if (preg_match($pattern, $url)) { echo "ある"; } else { echo "ない"; } ご指導のほど宜しくお願いします。

    • ベストアンサー
    • PHP
  • preg_matchと定数について

    preg_matchと定数について $string = "○○ドメイン"; if (preg_match("/$string/", $_SERVER['SERVER_NAME'])) {  echo "○"; } else {  echo "✕"; とやると○になるのですが、 define("DOMAIN", "○○ドメイン"); if (preg_match("/DOMAIN/", $_SERVER['SERVER_NAME'])) {  echo "○"; } else {  echo "✕"; } とすると、✕になります。 なぜでしょうか?

    • ベストアンサー
    • PHP
  • PHPで似たコードを繰り返す場合の簡潔な書き方??

    ご質問失礼します。 PHPでデータベースのデータを下記のようなコードを使い表示しています。 ※質問内容に該当する一部のみ記載させていただいています ・ ・ ・ ・ ・ if(preg_match("/新規/", $row['status1'])){ $table .= $row['status1']." 新規です"; } else { if(preg_match("/更新/", $row['status1'])){ $table .= $row['status1']." 更新です"; } else { if(preg_match("/削除/", $row['status1'])){ $table .= $row['status1']." 削除です"; } else { $table .= "いません"; } } } if(preg_match("/新規/", $row['status2'])){ $table .= $row['status2']." 新規です"; } else { if(preg_match("/更新/", $row['status2'])){ $table .= $row['status2']." 更新です"; } else { if(preg_match("/削除/", $row['status2'])){ $table .= $row['status2']." 削除です"; } else { $table .= "いません"; } } } if(preg_match("/新規/", $row['status3'])){ $table .= $row['status3']." 新規です"; } else { if(preg_match("/更新/", $row['status3'])){ $table .= $row['status3']." 更新です"; } else { ・ ・ ・ ・ ・ ・ status1から、5つあればstatus5まで、似たようなPHPを繰り返し書いて動作させています。 このような場合、簡潔に書く方法などありますでしょうか。 ご存知の方いらっしゃいましたらお時間のある際にお教え下さいませんでしょうか。 また、簡潔に書く方法がない場合でも無いとお教えいただければ幸いです(○ `人´ ○)

    • ベストアンサー
    • PHP
  • 正規表現のコーディングについてお願いします。

    こんにちは、よろしくお願いいたします。 正規表現パターンを書く場合に皆さんがどのようにされているか教えてください。 例えば(ちょっとムリヤリ感が強いですが)、'Price \5800-' という文字列の \5800 の部分に preg_match でマッチさせたいとします。 単純に考えると、 /\\\d+/ のようなパターンが思いつくのですが、それを文字列として preg_match に渡す際に、コードはどのように書かれますか? <?php   $str = 'Price \5800-';   //とりあえず、'/\\\d+/' と書き、'/\\\\\\d+/' と、\ をそれぞれの \ に書き足す   if ( preg_match('/\\\\\\d+/', $str, $match) ) {     print_r($match);   } ?> 「まず、パターンを書き、全ての \ の前に \ を書き足す。」というのが無難なのかな?と思い、そうしていますが、 そういった考え方で間違っていないでしょうか? どうぞよろしくお願いいたします。

    • 締切済み
    • PHP
  • 正規表現の\\が認識されない?

    現在、PHPで正規表現を用いてURLをホスト名・パス名・クエリー部分を分けて出力するPGを作成しているのですが。 どうやら、'\\'が'\'(バックスラッシュ)として表現できていないようなのですが? なぜでしょうか? ご教授お願いいたします。 【PG】 $regexが正規表現内容 ↓ $regex = '/^(?:https?|ftp):\/\/([-.!~*\'()\w;:\@&=+\$,%#]+)\/?([-.!~*\'()\w;\/:\@&=+\$,%#]*)\??([\\-.!~*\'()\w;\/:\@&=+\$,%#]*)$/'; if( preg_match($regex, $str, $match) ) { echo $match[1]."\t".$match[2]."\t\n"; } else { echo "URLではありません。\n"; }

    • 締切済み
    • PHP
  • += -= *= /= を判別する正規表現

    PHP5.2.4を使用しています。 $key = 'a +='; $val = 2; の場合に、 a = a + 2 となるように変換するためには preg_match(ここに何か記述, $key, $match)を使ってどのように記述すれば良いのでしょうか? 例えば、次の条件だったら $key = 'a -='; $val = 2; a = a - 2 と変換したいです。 if (preg_match(ここに何か記述, $key, $match)) {  ここで$keyと$valと$matchを使って  a = a (+ or - or * or /) 2となるように記述すると思うのですが }

    • ベストアンサー
    • PHP
  • 正規表現について

    いつもお世話になっております。 perlの正規表現で分からない事があります。 ご存知の方がいらっしゃれば、アドバイスを頂けますようよろしくお願い致します。 (質問内容) 以下のようなプログラムを実行した場合、matchが出力されてしまいます。 $aには、「、IS」を設定しているので、「真」と扱われないと思うのですが、何故、matchが出力されるのでしょうか? また、「偽」として処理をいしたい場合、 どのようにすればよろしいのでしょうか? #!/usr/bin/perl $a = "、IS"; $b = "AIS"; if ($a =~ $b){ print "match\n"; } else{ print "not match\n"; }

専門家に質問してみよう