人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

<?xml version="1.0" encoding="SHIFT_JIS"?>の、
要素に日本語文字(他のマルチバイト文字も含む)が使われている
xmlファイルをパースして、
その文字を一文字ずつ取り出し、SJISのコード値の指定のものだったら
cp932のコード値に変換して、保存する、Javaソースコードがあります。
前任者がで書いたこのコードを、PHPに書き直してくれと言われました。
(言っている人は、JavaもPHPも詳しくないSEです。)

前任者の方は その文字列(Stringオブジェクト)から、charAt( )で
一文字ずつ取り出し、switch文で指定のSJISコード値かどうかを
判定しています。
例.
case '\u2014':// '―' だったら、
→ \u2015 に置き換え。
case '\u301C':// '?' だったら、
→ \uFF5E に置き換え。
case '\u00A2':// '?' だったら、
→ \uFFE0 に置き換え。
case '\u00A3':// '?' だったら、
→ \uFFE1 に置き換え。
といった具合にです。

そこで質問ですが、このような判定をPHPでは、出来なくない
ですか?マルチバイト文字を一文字ずつ取り出す方法ってある
でしょうか?

●質問者: gdwtseq
●カテゴリ:ウェブ制作
○ 状態 :終了
└ 回答数 : 3/3件

▽最新の回答へ

1 ● きゃづみぃ
●34ポイント

http://php.net/manual/ja/function.str-replace.php

PHPにはstr_replaceという置換の関数があります。


gdwtseqさんのコメント
こちらのサイトを参考にしようとしていますが、 http://d.hatena.ne.jp/tamamo-ch/20090730 xmlファルイがShift_JISだからなのか、苦戦してます。 sjis.xml <root> <youso>波ダッシュ〜全角チルダ?<youso> </root> chikan.php(エンコーディングは、SIIS)は、処理PHPファですが。 <?php $utf_escape_patterns =array( // 波ダッシュを全角チルダ(?)へ変換 '/\xE3\x80\x9C/' =>"\xEF\xBD\x9E", // 全角マイナス記号(?)の変換 '/\xE2\x88\x92/' =>"\xEF\xBC\x8D", // 双柱・平行記号(?)の変換 '/\xE2\x80\x96/' =>"\xE2\x88\xA5", // セント記号(?)の変換 '/\xC2\xA2/' =>"\xEF\xBF\xA0", // ポンド記号(?)の変換 '/\xC2\xA3/' =>"\xEF\xBF\xA1", // 否定記号(?)の変換 '/\xC2\xAC/' =>"\xEF\xBF\xA2", ); $buf = mb_convert_encoding( file_get_contents( './sjis.xml'), 'UTF-8', 'SJIS'); $html =preg_replace( array_keys($utf_escape_patterns), array_values($utf_escape_patterns), $buf ); echo $html; ?> これで、波ダッシュ'〜'が全角チルダ'?'に置換できません。 アドバイス頂けると助かります。 お願いします。

きゃづみぃさんのコメント
>|php| $buf = mb_convert_encoding( file_get_contents( './sjis.xml'), 'UTF-8', 'SJIS'); $e1 = mb_convert_encoding('/\xE3\x80\x9C/' , 'utf8', 'sjis-win'); $html = preg_replace($e1,"\xEF\xBD\x9E",$buf); ||< こんな感じで正規表現を使うなら置換できると思いますが。

きゃづみぃさんのコメント
>|php| <?php $buf = mb_convert_encoding( file_get_contents( './sjis.xml'), 'UTF-8', 'SJIS'); // 波ダッシュを全角チルダ(?)へ変換 $html =preg_replace( mb_convert_encoding('/\xE3\x80\x9C/', 'utf8', 'sjis-win'), "\xEF\xBD\x9E", $buf); // 全角マイナス記号(?)の変換 $html =preg_replace( mb_convert_encoding('/\xE2\x88\x92/', 'utf8', 'sjis-win'), "\xEF\xBC\x8D", $html); // 双柱・平行記号(?)の変換 $html =preg_replace( mb_convert_encoding('/\xE2\x80\x96/', 'utf8', 'sjis-win'), "\xE2\x88\xA5", $html); // セント記号(?)の変換 $html =preg_replace( mb_convert_encoding('/\xC2\xA2/', 'utf8', 'sjis-win'), "\xEF\xBF\xA0", $html); // ポンド記号(?)の変換 $html =preg_replace( mb_convert_encoding('/\xC2\xA3/', 'utf8', 'sjis-win'), "\xEF\xBF\xA1", $html); // 否定記号(?)の変換 $html =preg_replace( mb_convert_encoding('/\xC2\xAC/', 'utf8', 'sjis-win'), "\xEF\xBF\xA2", $html); echo $html; ?> ||<

2 ● oil999
●33ポイント

PHPのmb_substr関数を使えば、マルチバイト文字を1文字ずつ取り出せます。
http://php.net/manual/ja/function.mb-substr.php


3 ● a-kuma3
●33ポイント

mb_strlen で、マルチバイト文字列としての文字数を取得して、それでループしながら mb_substr でマルチバイトとしての1文字ずつを切り出していく、という感じになると思います。
http://www.php.net/manual/ja/function.mb-strlen.php
http://www.php.net/manual/ja/function.mb-substr.php
# 効率悪そう...

mb_ereg_replace_callback か mb_ereg_replace を使うと、もうちょっとスマートに書けそうな気もしますが、ソースの移植なら愚直に元のコードのロジックをそのまま使う、という方がトラブルが少ないような気もします。
http://www.php.net/manual/ja/function.mb-ereg-replace-callback.php
http://www.php.net/manual/ja/function.mb-ereg-replace.php

関連質問

●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ