トップ回答者
Unicode→Shift_JIS変換時に、Shift_JISに存在しない文字を数値参照文字にする方法

質問
-
Shift_JIS形式のテキストファイルを編集するアプリケーションを作成中で、Shift_JISに存在しない文字も読み書きしたいと考えております。
その為、保存時にShift_JISに存在しない文字を数値参照文字に変換したいのですが、.NET Frameworkにそのような変換を行ってくれるクラスはあるのでしょうか?存在しない場合、代替手段としてどのような手段が考えられますでしょうか?
具体的には、以下のような処理をする予定です。
①Shift_JIS形式のテキストファイルを読み込む
②数値参照文字をデコード(これはSystem.Web.HttpUtility.HtmlDecodeメソッドでできました)
③Unicodeで編集
④Unicodeに存在し、Shift_JISに存在しない文字を数値参照文字に変換 ←ここが分かりません
⑤変換後のテキストを保存
以上、お手数ですが、宜しくお願いします。
- 編集済み しげおQk 2017年1月12日 10:11
回答
-
一案ですが。
- Encoding.GetEncodingで、EncoderExceptionFallbackを渡してEncodingを取得する。
- Encoding.GetEncoder()で取得できるEncoderを使って、入力文字列をchar1つずつ、順次Convertでbyte[]に変換する。
- Convertが成功した場合、出力先のFileStreamに変換されたbyte[]を出力する。
- Convertで例外が出た場合、出力先のFileStreamに、"&#" + (int)character + ";" をbyte[]化したものをFileStreamに出力する。
とか。
まじめに実装するなら、EncoderFallback/EncoderFallbackBufferを自前で実装し、Fallback時に数値文字参照を返すようにする、でしょうかね。
数値文字参照を使うのなら、元のテキストに生の & を使用できなくなるのでこれのエスケープも考えないと行けませんね。
あと、HtmlDecodeを使うと、HTMLの実体参照類も勝手にデコードされてしまいますが大丈夫ですか?(&さえ正しくエスケープされてれば大丈夫だったかな…)。なお、非webアプリ用に、System.Net.WebUtilityクラスの方にメソッドが用意されています。
- 回答としてマーク しげおQk 2017年1月12日 21:03
-
一例です。
private string convertToShiftJIS(string str) { string output = ""; foreach(char c in str) { if (isUnicodeChar(c)) { StringBuilder sb = new StringBuilder(); sb.AppendFormat("&#x{0:x};", (int)c); output += sb.ToString(); } else { output += c; } } return output; } private bool isUnicodeChar(char c) { string checkString = c.ToString(); byte[] translateBuffer = Encoding.GetEncoding("shift_jis").GetBytes(checkString); string translateString = Encoding.GetEncoding("shift_jis").GetString(translateBuffer); return (checkString != translateString.ToString()); }
もっと効率の良い方法があるかもしれませんが、、参考サイト:
http://acha-ya.cocolog-nifty.com/blog/2010/12/unicode-ef79.html- 編集済み kenjinoteMVP 2017年1月12日 11:39
- 回答としてマーク しげおQk 2017年1月12日 21:03
すべての返信
-
一案ですが。
- Encoding.GetEncodingで、EncoderExceptionFallbackを渡してEncodingを取得する。
- Encoding.GetEncoder()で取得できるEncoderを使って、入力文字列をchar1つずつ、順次Convertでbyte[]に変換する。
- Convertが成功した場合、出力先のFileStreamに変換されたbyte[]を出力する。
- Convertで例外が出た場合、出力先のFileStreamに、"&#" + (int)character + ";" をbyte[]化したものをFileStreamに出力する。
とか。
まじめに実装するなら、EncoderFallback/EncoderFallbackBufferを自前で実装し、Fallback時に数値文字参照を返すようにする、でしょうかね。
数値文字参照を使うのなら、元のテキストに生の & を使用できなくなるのでこれのエスケープも考えないと行けませんね。
あと、HtmlDecodeを使うと、HTMLの実体参照類も勝手にデコードされてしまいますが大丈夫ですか?(&さえ正しくエスケープされてれば大丈夫だったかな…)。なお、非webアプリ用に、System.Net.WebUtilityクラスの方にメソッドが用意されています。
- 回答としてマーク しげおQk 2017年1月12日 21:03
-
一例です。
private string convertToShiftJIS(string str) { string output = ""; foreach(char c in str) { if (isUnicodeChar(c)) { StringBuilder sb = new StringBuilder(); sb.AppendFormat("&#x{0:x};", (int)c); output += sb.ToString(); } else { output += c; } } return output; } private bool isUnicodeChar(char c) { string checkString = c.ToString(); byte[] translateBuffer = Encoding.GetEncoding("shift_jis").GetBytes(checkString); string translateString = Encoding.GetEncoding("shift_jis").GetString(translateBuffer); return (checkString != translateString.ToString()); }
もっと効率の良い方法があるかもしれませんが、、参考サイト:
http://acha-ya.cocolog-nifty.com/blog/2010/12/unicode-ef79.html- 編集済み kenjinoteMVP 2017年1月12日 11:39
- 回答としてマーク しげおQk 2017年1月12日 21:03