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です。
No.2ベストアンサー
- 回答日時:
preg_replaceはマルチバイトに対応していません。
全角半角は 81 40 なので、それに該当したバイトコード全てを削除しようとします。
「あ」は82 A0なので文字化けはしないと思いますが・・・
「@」(40)が先頭にあったり、81で始まるマルチバイト文字が先頭にある場合は文字化けすると思われます。
正規表現をそのままにmb_ereg_replace()を使うと良いと思われます。
>trim()
マルチバイトでは正常に動かないんじゃないかなぁ。
試してないので分かりませんが。
この回答への補足
preg_replace試してみました。
$after = mb_ereg_replace('^[ \r\n]*(.*?)[ \r\n]*$', '\1', $before);
結果:
<入力>
ああ
<出力>
??ああ
あれれ・・・
回答を即座にいただいて喜び勇んでやってみたのですが、
うまくいかず・・・どこか間違っているでしょうか??
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が抜けているということはないでしょうか。
この回答への補足
続きですが当方の環境では以下のようになっているようです。
あ:e3 81 82
全角スペース:e3 80 80
半角スペース:20
\r:5c
\n:6e
置換時に指定する文字列として、全角スペースの"e3 80 80"が"e3"として解釈されてしまい、正常に動かないものと考えられます。
現在、3バイトでも置換する方法を調べているところです。
mb_ereg_replaceで可能なのか、他に関数が用意されているのか、
それとも自作するしかないのでしょうか・・・
訂正いたします:
あ:e3 81 82
全角スペース:e3 80 80
半角スペース:20
\r:5c 72
\n:5c 6e
またまたお礼欄を利用して訂正いたしますことご容赦ください
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()ではなく別に原因があることになります。
先頭にゴミが入っていれば、正規表現にもう一工夫する必要があるかと。
/// だれかズバッとした答えを書いてくれないかなぁ(:>^
この回答への補足
続けての回答ありがとうございます。
試してみたところ、以下のような出力が得られました。
「あ」置換前>あ: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バイト…?当方の知識不足でよくわかりません、すいません。
質問締め切り後のお礼文です。
以下のコードで意図した通り動くようになりました。
mb_regex_encoding('UTF-8');
$after = mb_ereg_replace('^[ \r\n]*(.*?)[ \r\n]*$', '\1', $before);
基本的なところで詰まっていたようで、encodingの種類を指定することで動くようになりました。
preg_replaceによる置換はうまくいくかと思いきや、改行コードや半角スペースを織り交ぜてテストしてみるとうまくいかないことがありますので、こちらが最終形なのではないかと思っております。
皆様ありがとうございました。
特に何度も回答いただいたwp_さんには感謝です。
No.3
- 回答日時:
typoした...orz
>全角半角
全角空白ですな。
罪滅ぼしといってはナンですが、trim()調べました。
結論から述べると「いけそうです」
trim()を使うのが手軽で良いかもしれません。
$str = " @@@@test@@@@ "; // 全角空白あり
echo $str."<br />";
echo trim($str," ");
↓
@@@@test@@@@ ←全角空白がある状態
@@@@test@@@@←trim()を噛んだ状態
この回答への補足
進展はしていませんが、\マーク1つだとまずいらしく、\\に置き換えて
テストしてみた結果を報告します。
$after = mb_ereg_replace('^[ \\r\\n]*(.*?)[ \\r\\n]*$', '\1', $before);
結果:
<入力>
ああ
<出力>
??ああ
変わりませんでした。むむ・・・
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・14歳の自分に衝撃の事実を告げてください
- ・架空の映画のネタバレレビュー
- ・「お昼の放送」の思い出
- ・昨日見た夢を教えて下さい
- ・ちょっと先の未来クイズ第4問
- ・【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
- ・メモのコツを教えてください!
- ・CDの保有枚数を教えてください
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・ハマっている「お菓子」を教えて!
- ・最近、いつ泣きましたか?
- ・夏が終わったと感じる瞬間って、どんな時?
- ・10秒目をつむったら…
- ・人生のプチ美学を教えてください!!
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
メッセージボックスで1025文字...
-
文字の入力で横バー上段、中断...
-
エクセルのCOUNTIFが正しくカウ...
-
全角括弧と全角読点の間隔を狭...
-
XMLのタグ名の禁則文字
-
Excel関数「COUNTIF」で”文字”...
-
VB.net テキストボックス半角文...
-
Accessの文字数を調べたい
-
IT企業の技術屋にとって全角英...
-
なぜインターネットでは半角カ...
-
Python 正規表現でsetと=の間の...
-
文字列前後の「全角空白/半角空...
-
文字列中の両丸括弧を取り除くV...
-
Replace関数は文字数の制限ある...
-
半角記号、全角記号を含む正規...
-
VBAで英数字入力チェックしたい。
-
rawurlencodeとurlencodeの違い...
-
VBのソース検索で、コメントア...
-
ColdFusionにて
-
Phonetic関数を利用して文章中...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
文字の入力で横バー上段、中断...
-
メッセージボックスで1025文字...
-
全角括弧と全角読点の間隔を狭...
-
エクセルのCOUNTIFが正しくカウ...
-
Excel関数「COUNTIF」で”文字”...
-
エクセルでの漢字、カタカナ、...
-
記号は半角と全角どちらがよい...
-
半角記号、全角記号を含む正規...
-
なぜインターネットでは半角カ...
-
VBScriptである文字列に半角文...
-
パソコンで全角、半角文字の切...
-
文字列中の両丸括弧を取り除くV...
-
VBAで英数字入力チェックしたい。
-
全角英数文字が嫌われる理由を...
-
エスケープ文字にstr_replaceが...
-
XMLのタグ名の禁則文字
-
全角英数字のみ半角英数字にす...
-
eval 半角カナが文字化けする
-
Replace関数は文字数の制限ある...
-
半角英数字のみを受け付ける入...
おすすめ情報