DOBON.NET DOBON.NETプログラミング掲示板過去ログ

ユニコードエスケープ文字のエンコードについて

環境/言語:[.NET Framework2.0 / C#]
分類:[.NET]

いつも参考にさせていただいています。

実は、ファイルに格納している以下の文字列
「今日は、\u702c\u6238へ行く。」
を読み込もうとしています。

この際、unicodeをエスケープ表記している部分が
漢字の「瀬戸」にならなくて困っております。

ネットでも調べましたが、上手くヒットしません。

どなたかお知恵を拝借願えればと存じポストいたしました。
それは、普通にテキストファイルから StreamReader など使って読み出しており、
メモ帳で開いた場合「\u702c」などと表示される物ですか?

Unicode 文字エスケープシーケンスは、C# コンパイラがコンパイル時に文字列リテラルを用意する際に、ソースコード上の \uXXXX と記述されている部分を Unicode の U+XXXX という文字に置き換えるもので、あくまでコンパイラの機能です。
アプリケーション実行時に、ファイルを読み込んだときに勝手にそれを Unicode 文字エスケープシーケンスだと解釈してしまうような機能はありません。
// 勝手にそんなことされたら、『「瀬」という漢字は「\u702c」と書けます』というテキストファイルを正しく読み取ることができなくなってしまいます。

ファイルを読み込んだ後、正規表現など使って置換するようにしましょう。
Hongliangさん

迅速な回答ありがとうございます。
本質問は、普通にテキストファイルから StreamReader など使って読み出しており、メモ帳で開いた場合「\u702c」などと表示される物についてです。

確かにこの機能はソースコード上の文字の置き換えですね・・

以前、メモ帳で開いた場合「\n」に表示されるものに関し、似た様なことを対応しようとして、

str.Relpace("\\n", "\n");

で良かったのですが、今回
str.Relpace("\\u", "\u");
としても、"\u"が正しいエスケープシーケンスでないのでコンパイル時にエラーしてしまいます。

>
> ファイルを読み込んだ後、正規表現など使って置換するようにしましょう。

正規表現を考えてみるものの、System.Text.RegularExpressions.Regex.Replaceを使ったらよいのではと思うのですが、正規表現が今ひとつ思いつきません・・・

お知恵をお願いします。
MatchEvaluator を使ってこんな感じです。

string text = File.ReadAllText(file);
// \u は Regex でも Unicode エスケープシーケンスとして扱われるので
// 文字列「\u」にマッチさせるには \\u と表現する必要がある。
// さらに C# レベルで \ をエスケープするために \ 一つを \\ と記述する。
// C# レベルのエスケープが面倒なら逐語的リテラル文字列を使うのも手。
text = Regex.Replace(text, "\\\\u(?<code>[0-9a-fA-F]{4})", Replace);

static string Replace(Match m) {
    int code = Convert.ToInt32(m.Groups["code"].Value, 16);
    // char 型は UTF-16 で同等の数値型と可換。
    return ((char)code).ToString();
}

なお、C# の Unicode 文字エスケープシーケンスは厳密には UTF-16 で表現する物なので、
基本多言語面(BMP)以外の文字はサロゲートペアとして二つの \uXXXX で表記されます。
上記変換関数もそのように扱っています。
2010/08/15(Sun) 16:56:26 編集(投稿者)

Hongliangさん

迅速な回答ありがとうございます。
この方法で、対応することが出来ました。
エレガントなお答え、ありがとうございます!

自分は、正規表現が不得意なので、アドホック的に以下のように対処しようとしていました・・・

    private string convertHexUnicode(string intext) 
    {
      char [] array = intext.ToCharArray();
      string outstr = "";

      for( int i = 0; i<array.Length; i++ ) 
      {
        if( array[i] != '\\' ) 
        {
          outstr += array[i].ToString();
        }
        else 
        {
          // array[i] == '\\'

          if( i < array.Length-1 && array[i+1] == 'u' ) 
          {
            try 
            {
              string tmpstr = "";

              tmpstr += array[i+2];
              tmpstr += array[i+3];
              tmpstr += array[i+4];
              tmpstr += array[i+5];

              int tmpi = int.Parse(tmpstr, System.Globalization.NumberStyles.HexNumber);

              outstr += (char) tmpi;
              i+=5;

            }
            catch 
            {

            }
          }
        }
      }

      return outstr;
    }
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板