テキストファイルを文字列にロードし、すべてのUnicodeエスケープを文字列内の実際のUnicode文字に変換するとします。
例:
「以下はUnicode '\ u2320'の積分文字の上半分であり、これは下半分 '\ U2321'です。」
答えは簡単で、少なくとも数千文字までの文字列でうまく機能します。
例1:
Regex rx = new Regex( @"\\[uU]([0-9A-F]{4})" );
result = rx.Replace( result, match => ((char) Int32.Parse(match.Value.Substring(2), NumberStyles.HexNumber)).ToString() );
例2:
Regex rx = new Regex( @"\\[uU]([0-9A-F]{4})" );
result = rx.Replace( result, delegate (Match match) { return ((char) Int32.Parse(match.Value.Substring(2), NumberStyles.HexNumber)).ToString(); } );
最初の例は、ラムダ式(C#3.0)を使用して行われる置換を示し、2番目の例はC#2.0で機能するデリゲートを使用しています。
ここで何が起こっているかを分析するために、最初に正規表現を作成します。
new Regex( @"\\[uU]([0-9A-F]{4})" );
次に、Replace()を文字列 'result'と、文字列で見つかった各正規表現を変換する匿名メソッド(最初の例ではラムダ式、2番目の例ではデリゲート-デリゲートは通常のメソッドでもかまいません)で呼び出します。 。
Unicodeエスケープは次のように処理されます。
((char) Int32.Parse(match.Value.Substring(2), NumberStyles.HexNumber)).ToString(); });
エスケープの数値部分を表す文字列を取得します(最初の2文字をスキップします)。
match.Value.Substring(2)
Int32.Parse()を使用してその文字列を解析します。これは、Parse()関数が予期する文字列と数値形式(この場合は16進数)を取ります。
NumberStyles.HexNumber
次に、結果の数値をUnicode文字にキャストします。
(char)
そして最後に、Unicode文字でToString()を呼び出します。これにより、Replace()に返される値である文字列表現が得られます。
.ToString()
注:Substring呼び出しで変換するテキストを取得する代わりに、matchパラメーターのGroupCollectionと正規表現の部分式を使用して、数値( '2320')のみをキャプチャできますが、これはより複雑で読みにくくなります。
もう少しリファクタリング:
Regex regex = new Regex (@"\\U([0-9A-F]{4})", RegexOptions.IgnoreCase);
string line = "...";
line = regex.Replace (line, match => ((char)int.Parse (match.Groups[1].Value,
NumberStyles.HexNumber)).ToString ());
これはVB.NETと同等です。
Dim rx As New RegularExpressions.Regex("\\[uU]([0-9A-Fa-f]{4})")
result = rx.Replace(result, Function(match) CChar(ChrW(Int32.Parse(match.Value.Substring(2), Globalization.NumberStyles.HexNumber))).ToString())
正規表現に小文字を追加したほうがいいと思います。それは私にとってよりうまくいきました。
Regex rx = new Regex(@"\\[uU]([0-9A-Fa-f]{4})");
result = rx.Replace(result, match => ((char) Int32.Parse(match.Value.Substring(2), NumberStyles.HexNumber)).ToString());