Asial Blog

Recruit! Asialで一緒に働きませんか?

mb_eregで日本語検索すると・・

カテゴリ :
バックエンド(プログラミング)
タグ :
Tech
PHP
こんばんは、笹亀です。
技術ブログの当番が自分にも回ってきました。
何を書かせていただこうかと考えに考えたのですが、
難しいことをご紹介するのは優秀な技術者の皆さんにお任せする方向にします(笑

私は、PHPを使いなれている人もそうでない人も、
普通に使っているとあまり知らない問題を紹介したいと思います。

今回、実際に使用していた関数はmb_ereg関数で、
日本語(マルチバイト)の文字列を正規表現マッチを行なう関数ですね。

実験した環境は、
内部エンコーディングは「UTF-8」と設定しています。
ファイルは「EUC-JP」で実験してみました。

まずは、普通にmb_ereg関数を使用してみました。
違いが出るかもしれないとおもい、eregも追加しました。
  1. <?php
  2. var_dump(mb_ereg("", "タイトルイと2あああああ"));
  3.  
  4. var_dump(mb_ereg("タイトル", "タイトル2あああああ"));
  5.  
  6. var_dump(ereg("", "タイトルイと2あああああ"));
  7.  
  8. var_dump(ereg("タイトル", "タイトル2あああああ"));
  9.  
  10. //全部trueだと思ってテスト
  11. ?>
結果はこうなりました。
  1. bool(false) bool(false) int(1) int(1) 

「なんでereg関数だけがtrueなんだろうか?」
日本語を使用しているので、
eregではなくやっぱりmb_eregを使ってパターンマッチさせたいと思いますよね・・・
文字コードや日本語問題で悩んだときに、必ず「日本人を辞めたい」と思ってしまうのは僕だけでしょうか?

さぁ・・気を取り直して問題解決のためにいろいろ調べておりました。
原因は簡単なことでした。
「mb_regex_encoding」でマルチバイト対応の正規表現を使用される文字エンコーディングの設定が、
使用エンコードと違うため誤動作をしていたみたいです。

上記の設定をしないでマルチバイト対応の正規表現を使用すると内部文字エンコーディングに設定されてしまいます。
これにより、下記のように記述しました。
  1. <?php 
  2. mb_regex_encoding("EUC-JP");
  3.  
  4. var_dump(mb_ereg("", "タイトルイと2あああああ"));
  5.  
  6. var_dump(mb_ereg("タイトル", "タイトル2あああああ"));
  7.  
  8. var_dump(ereg("", "タイトルイと2あああああ"));
  9.  
  10. var_dump(ereg("タイトル", "タイトル2あああああ"));
  11.  
  12. //今度こそ全部trueだと思ってテスト
  13. ?>
結果
  1. int(1) int(1) int(1) int(1) 
やっと、思い通りに動作してくれました。
「mb_regex_encoding」の設定の存在に気が付けばすぐに解決はできますね。

普段は内部エンコーディングとファイルの文字コードなどは統一された環境が一般的だと思います。そういったときには上記の設定を意識せずに使うことができるのでこの関数を使用して設定の変更を行なうことはないと思います。
しかし、今回の自分の環境がちょっと不思議な環境だったので、
こういった問題が起こりました。

おまけで、気になったのでこんなことをしてみました。
mb_regex_encoding()で文字コードの指定をしないと内部文字エンコーディングに依存するなら、下記のようになっていたら動きそうな気がしてテストしてみました。
  1. <?php 
  2. mb_internal_encoding("EUC-JP");
  3.  
  4. var_dump(mb_ereg("", "タイトルイと2あああああ"));
  5.  
  6. var_dump(mb_ereg("タイトル", "タイトル2あああああ"));
  7.  
  8. var_dump(ereg("", "タイトルイと2あああああ"));
  9.  
  10. var_dump(ereg("タイトル", "タイトル2あああああ"));
  11.  
  12. //mb_eregは「mb_regex_encoding」の指定がないと内部エンコーディングを参照するらしいので、
  13. //内部エンコーディングの設定を変えたらきっと変わって動いてくれるはずだ・・
  14. ?>
結果
  1. bool(false) bool(false) int(1) int(1) 
あれ?見事に期待を裏切ってくれました。

  1. <?php 
  2. mb_internal_encoding("EUC-JP");
  3. print mb_regex_encoding();
  4. ?>
確認で上記のテストをしてみると・・・
「UTF-8」と表示されました。
内部エンコーディングを手動で変更しても、
mb_regex_encodingのデフォルトにはなってくれないみたいです。

関数でも使い方によってはちゃんと動いたり動かなかったりと、
このようなものを見つけたときは不思議とエンジニアの血が騒ぎます。
こういったことが好きな方でつい、
いろんなことをしたくなってしまいます。

皆さんも「他にもこういった面白い動作するものがある」とかありましたら、
是非、教えてください。

コメント

  •  

    レゲックスのエンコードはまるよね

  • 使えないソフトだな

    一度もurlからPDFに変換できねぇじゃねえか。
    えれーつかえねっぇ

  • ELF

    超きわめるPHPに記述されている内容です;)
    持ってる人に借りて読んでみてください

  • 笹亀弘

    >ELFさん
    貴重なコメントありがとうございます。
    超極めるPHPに記述されていた内容と知らずに・・
    早速、自分の内容と照らし合わせながら、
    読んでみたいとおもいます。

  • はまり男

    機種依存文字や正規表現で検索していたらここに辿りつきましたので初心者ながら質問させていただきます。

    登録情報を入力してもらうフォームで機種依存文字が入っていた場合に①→(1)などに変換したいと思っております。ググってそんな感じの関数を発見致して適用してみましたが他の機種依存文字以外でどうも文字化けしてしまいます・・・ 

    こんな感じでやっています。(文字コードEUC)

    $_POST["contents"] = izon_win($_POST["contents"]);

    関数URL
    http://www.shibata.tv/essay/essay_515.htm

    お時間がありましたらよろしくお願いします

  • 笹亀弘

    >はまり男さん
    コメントの投稿ありがとうございます。

    実行された環境などがわからないので、あまり正確なことがもうしあげれませんが、日本語関連の設定が原因なのではないでしょうか?
    私自身もその関数で機種依存文字のチェックをしてみました。関数自体は正常に動作しておりその他の日本語も表示されました。

    mb_http_inputやmb_http_output
    などのフォームからの文字コードのinputとoutputの設定がEUC-JPの設定になっていないのではないのでしょうか?
    日本語の設定関連は正しく設定を行なわないと、文字化けを頻繁に起こします。文字コードの設定をご確認いただくとよろしいかとおもいます。

    この関数では、定義されていない、その他の機種依存文字は関数の変換しているリストに追加していかないと「?」のように文字として表現できなくなります。
    機種依存文字リスト
    http://blog.club.jp/archives/2007/01/post_56.html

    また、弊社が運営しているphpのコミュニティサイト(http://www.phppro.jp/)のQA掲示板で質問を記述していただけると、登録していただいているPHPプログラマーの方々から、返信していただけるとおもいます。よろしかったら、ご覧ください^^

    ご参考になれば、幸いでございます。

  • はまり男

    ヒントをくれてありがとうございます。

    さっそく明日チャレンジします、尚これからはphpproの方に質問させていただきます!

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

  • りも

    PHP4のサーバからPHP5のサーバに移転した所、今まで動いていたmb_ereg_replaceがNG。ここで解決しました。助かりました。mb環境が確かに変わっていました。

  • 笹亀弘

    >りもさん
    PHP4サーバとPHP5サーバでのPHPのデフォルトの設定が違う関係で起こった問題なのだとおもいます。
    私のブログ内容が少しでもお力になれたということでうれしく思います^^

  • もんた。

    本当に、助かりましたー。

  • 石川

    ありがとう!解決しました!!

  • 笹亀弘

    コメントいただきありがとうございます。
    皆様のお力になれてよかったです^^

  • masamax.net

    ありがとうございます。
    今でも、この処理は必要なんですね。

コメントフォーム



captcha_key

アシアルの会社情報

アシアル株式会社はPHP、HTML5、JavaScriptに特化したWebエンジニアリング企業です。ユーザーエクスペリエンス設計から大規模システム構築まで、アシアルメンバーが各々の専門性を通じてインターネットの進化に貢献します。

会社情報詳細

最近の記事