<?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では、出来なくない
ですか?マルチバイト文字を一文字ずつ取り出す方法ってある
でしょうか?

回答の条件
  • URL必須
  • 1人5回まで
  • 登録:
  • 終了:2013/03/19 21:45:03
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

回答3件)

id:taknt No.1

回答回数13539ベストアンサー獲得回数1198

ポイント34pt

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

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

他1件のコメントを見る
id:taknt
$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);

こんな感じで正規表現を使うなら置換できると思いますが。

2013/03/14 10:54:49
id:taknt
<?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;
?>

2013/03/14 17:58:59
id:oil999 No.2

回答回数1728ベストアンサー獲得回数320

ポイント33pt

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

id:a-kuma3 No.3

回答回数4973ベストアンサー獲得回数2154

ポイント33pt

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

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません