• ベストアンサー

文字列前後の「全角空白/半角空白/改行文字」を取り除く

PHPで、「文字列の前後に付加されている全角空白/半角空白/改行文字を取り除く」 という処理をしたいのですが、以下のように置換処理を書くとうまくいきません。 $after = preg_replace('/^[  \r\n]*(.*)[  \r\n]*$/u', '$1', $before); // [  \r\n]→[半角空白、全角空白、改行文字]です どううまくいかないのかといいますと、入力として半角スペース+全角文字が入ったときに、全角文字の先頭文字が文字化けしてしまいます。 たとえば、 <半角スペース>あああ をこれにかけると、 <よくわからない文字>ああ となります。 以下のように2回に分けてみると、正常に動きます。 $tmp = preg_replace('/[  \r\n]*$/u', '', $before); $after = preg_replace('/^[  \r\n]*/u', '', $tmp); 最初のように1回の正規表現による置換で済ませたい場合、 どのように書くのが適切なのでしょうか? PHPのバージョンは5.2.3です。

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

  • ベストアンサー
  • wp_
  • ベストアンサー率54% (132/242)
回答No.2

preg_replaceはマルチバイトに対応していません。 全角半角は 81 40 なので、それに該当したバイトコード全てを削除しようとします。 「あ」は82 A0なので文字化けはしないと思いますが・・・ 「@」(40)が先頭にあったり、81で始まるマルチバイト文字が先頭にある場合は文字化けすると思われます。 正規表現をそのままにmb_ereg_replace()を使うと良いと思われます。 >trim() マルチバイトでは正常に動かないんじゃないかなぁ。 試してないので分かりませんが。

satori_jpn
質問者

お礼

お礼に記載して申し訳ないのですが、訂正します 結果: <入力> ああ <出力> ??あ です。大変失礼しました。

satori_jpn
質問者

補足

preg_replace試してみました。 $after = mb_ereg_replace('^[  \r\n]*(.*?)[  \r\n]*$', '\1', $before); 結果: <入力> ああ <出力> ??ああ あれれ・・・ 回答を即座にいただいて喜び勇んでやってみたのですが、 うまくいかず・・・どこか間違っているでしょうか??

その他の回答 (5)

  • kuzumiHK
  • ベストアンサー率72% (132/183)
回答No.6

$after = preg_replace('/^[  \r\n]*(.*?)[  \r\n]*$/u', '$1', $before); でも、 $after = mb_ereg_replace('^[  \r\n]*(.*?)[  \r\n]*$', '\1', $before); でも、きれいに置換され、 文字化けを再現することはできませんでしたが、 ↓preg_replaceでuをつけ忘れたときだけ、「??ああ」となりました。 $after = preg_replace('/^[  \r\n]*(.*?)[  \r\n]*$/', '$1', $before); 実行環境でuが抜けているということはないでしょうか。

satori_jpn
質問者

お礼

訂正いたします: あ:e3 81 82 全角スペース:e3 80 80 半角スペース:20 \r:5c 72 \n:5c 6e またまたお礼欄を利用して訂正いたしますことご容赦ください

satori_jpn
質問者

補足

続きですが当方の環境では以下のようになっているようです。 あ:e3 81 82 全角スペース:e3 80 80 半角スペース:20 \r:5c \n:6e 置換時に指定する文字列として、全角スペースの"e3 80 80"が"e3"として解釈されてしまい、正常に動かないものと考えられます。 現在、3バイトでも置換する方法を調べているところです。 mb_ereg_replaceで可能なのか、他に関数が用意されているのか、 それとも自作するしかないのでしょうか・・・

  • wp_
  • ベストアンサー率54% (132/242)
回答No.5

oopsあれー? と思ったけどよく考えたら当方の環境はEUCだったorz 平にご容赦。そして多謝。 >$after = mb_ereg_replace('^[  \r\n]*(.*?)[  \r\n]*$', '\1', $before); これで大丈夫な気はしますけどね。 $afterにunpack()噛ましてみて、??に化けている部分にどんなコードが入っているか確認すると原因が分かるかもしれません。 // 今手元に環境がないゆえ、確認できず $after = mb_ereg_replace('^[  \r\n]*(.*?)[  \r\n]*$', '\1', $before); $after_arr = unpack("C*",$after); foreach ($after_arr as $char_dec) { echo dechex($char_dec) . " ";} こうすると$afterの中身がバイナリ形式で分解され、16進数表示されます。 // 今手元に環境がないゆえ、typoあったら容赦 先頭のバイナリが不正でなければ、mb_ereg_replace()ではなく別に原因があることになります。 先頭にゴミが入っていれば、正規表現にもう一工夫する必要があるかと。 /// だれかズバッとした答えを書いてくれないかなぁ(:>^

satori_jpn
質問者

お礼

質問締め切り後のお礼文です。 以下のコードで意図した通り動くようになりました。 mb_regex_encoding('UTF-8'); $after = mb_ereg_replace('^[  \r\n]*(.*?)[  \r\n]*$', '\1', $before); 基本的なところで詰まっていたようで、encodingの種類を指定することで動くようになりました。 preg_replaceによる置換はうまくいくかと思いきや、改行コードや半角スペースを織り交ぜてテストしてみるとうまくいかないことがありますので、こちらが最終形なのではないかと思っております。 皆様ありがとうございました。 特に何度も回答いただいたwp_さんには感謝です。

satori_jpn
質問者

補足

続けての回答ありがとうございます。 試してみたところ、以下のような出力が得られました。 「あ」置換前>あ:e3 81 82 「あ」置換後>??:81 82 「ああ」置換前>ああ:e3 81 82 e3 81 82 「ああ」置換後>??あ:81 82 e3 81 82 e3ってなんだよってところでしょうか… というか入力が3バイトな気がします PHPソースはUTF-8で、サーバー環境もUTF-8で統一しております。 入力文字列はブラウザ経由なのでSJISだと思っていましたが3バイト…?当方の知識不足でよくわかりません、すいません。

  • php504
  • ベストアンサー率42% (926/2160)
回答No.4

NO3さんtrim( )はだめなようです 私の環境では@も消えちゃいましたよ PHP5.2.3で文字コードはsjisです 実行結果     @@@@test@@@@     test

satori_jpn
質問者

補足

皆さんありがとうございます。 おっしゃるとおり、trimでは全角未対応ということでほかの方法を探しております。 私の環境も入力文字列がSJISとなっており、trimでは正常に動作しない状態です。

  • wp_
  • ベストアンサー率54% (132/242)
回答No.3

typoした...orz >全角半角 全角空白ですな。 罪滅ぼしといってはナンですが、trim()調べました。 結論から述べると「いけそうです」 trim()を使うのが手軽で良いかもしれません。 $str = "    @@@@test@@@@    "; // 全角空白あり echo $str."<br />"; echo trim($str," "); ↓     @@@@test@@@@    ←全角空白がある状態 @@@@test@@@@←trim()を噛んだ状態

satori_jpn
質問者

補足

進展はしていませんが、\マーク1つだとまずいらしく、\\に置き換えて テストしてみた結果を報告します。 $after = mb_ereg_replace('^[  \\r\\n]*(.*?)[  \\r\\n]*$', '\1', $before); 結果: <入力> ああ <出力> ??ああ 変わりませんでした。むむ・・・

  • HIRSYU
  • ベストアンサー率51% (45/87)
回答No.1

trimではダメですか? ↓trimの仕様 http://www.php.net/manual/ja/function.trim.php