[[Open棟梁Project>http://opentouryo.osscons.jp/]] - [[マイクロソフト系技術情報 Wiki>http://techinfoofmicrosofttech.osscons.jp/]] -[[戻る>文字コード]] * 目次 [#m402c4a9] #contents *概要 [#e675a56e] 文字チェックは、文字化け等を事前に防ぐために行われる。 以下の文字チェック・ルーチンが一般的である。 *範囲チェック [#v36f5f1c] エンコード後に、範囲チェックをする。 **JIS第1第2水準漢字チェック [#b1013d54] ***仕様: [#k2306726] JIS第1第2水準漢字をチェックする ***実装: [#xe541f23] シフトJISのコード範囲でチェックを行う必要があるので、~ 一文字づつシフトJISにエンコード、数値型に変換し範囲チェックを行う。~ ***サンプルコード: [#h9211f32] -JISX0208_1983Checker~ https://github.com/OpenTouryoProject/OpenTouryo/blob/develop/root/programs/C%23/Frameworks/Infrastructure/Business/Str/JISX0208_1983Checker.cs //********************************************************************************** //* All Rights Reserved, Copyright (C) 2007,2012 Hitachi Solutions,Ltd. //********************************************************************************** //********************************************************************************** //* クラス名 :JISX0208_1983Checker //* クラス日本語名 :JIS X 0208-1983文字コード範囲チェック・クラス //* ・01~08区:記号、英数字、かな //* ・16~47区:JIS第1水準漢字 //* ・48~84区:JIS第2水準漢字 //* ※JIS X 0208-1990で追加された「凜[7425]」「熙[7426]」は含まれない //* ※NEC機種依存文字、NECのIBM拡張文字、IBM拡張文字は含まれない **Unicodeの外字範囲チェック [#x1bfc0d5] ***仕様: [#u1a9081d] Unicodeの外字範囲をチェックする。 -BMP領域 U+E000‐U+F8FF (6,400字) -15面 U+F0000‐U+FFFFD (65,534字) -16面 U+100000‐U+10FFFD (65,534字) -余談:シフトJISの外字範囲:U+E000~U+E757(0xF040~0xF9FC)。 ***実装: [#gef7b6ad] -一文字づつUnicode数値に変換し範囲チェックを行う。 -Java、.NETの文字列はUnicodeのためUnicodeの範囲チェックは、~ 以下の様なコードで簡単にチェックできる。~ (Unicode?JIS X 0221?各国の工業規格で使用されるか?)~ string from = "文字列を初期化する。" StringBuilder to = new StringBuilder(); foreach (char c in from) { int charCode = (int)c; if (57344 <= charCode && charCode <= 63743) { // Unicodeの外字範囲 // BMP領域 U+E000‐U+F8FF (6,400字) } else if (983040 <= charCode && charCode <= 1048573) { // Unicodeの外字範囲 // 15面 U+F0000‐U+FFFFD (65,534字) } else if (1048576 <= charCode && charCode <= 1114109) { // Unicodeの外字範囲 // 16面 U+100000‐U+10FFFD (65,534字) } else { // Unicodeの外字でない。 } } *個別チェック [#w00408c7] コード表で連続しない文字をチェックする。 **[[JIS2004>JIS2004関連]]チェック [#p7818a59] ***追加文字チェック [#ufd4fbd1] -仕様:~ [[JIS2004>JIS2004関連]]で追加された文字をチェックする。 -実装:~ Unicodeのみに存在し、コード範囲もバラバラなので、~ [[JIS2004>JIS2004関連]]追加文字配列を初期化し、一文字づつ、比較処理を行う。 ***サロゲートペア文字チェック [#td7ec057] -仕様:~ [[JIS2004>JIS2004関連]]で追加されたサロゲートペア文字をチェックする。 -実装: --Regex.IsMatch()メソッド、char.IsSurrogate()メソッドを使用する。 --Regex.IsMatch()メソッド(正規表現)を使用する。 ---以下サンプル・コード。 //ここに判定する文字列を入れる。 string strSurrogatesPair = textBox1.Text; Regex rg = new Regex("^[^\uD800-\uDBFF\uDC00-\uDFFF]+$"); //サロゲート ペア文字が文字列中に含まれているか //Regex.IsMatch() メソッド判定 if ( rg.IsMatch( strSurrogatesPair ) ) { // サロゲートペア文字が含まれていない。 } else { // サロゲートペア文字が含まれている。 } // 結合文字はチェックできない。 --char.IsSurrogate()メソッドを使用する。 ---以下サンプル・コード。 //ここに判定する文字列を入れる。 string strSurrogatesPair = textBox1.Text; //サロゲート ペア文字が文字列中に含まれているか //char.IsSurrogate()メソッドで判定 int i = 1; foreach (char ch in strSurrogatesPair.ToCharArray()) { if(char.IsSurrogate(ch)) { MessageBox.Show(i.ToString() + "文字目にサロゲート ペア文字が含まれています"); return; } else { i++; } } MessageBox.Show("サロゲート ペア文字が含まれていません"); ---サロゲート ペア文字を削除するサンプル コード //ここに判定する文字列を入れる。 string strSurrogatesPair = textBox1.Text; StringBuilder sb = new StringBuilder(); //サロゲート ペアが文字列中に含まれているか //char.IsSurrogate()メソッドで判定 foreach (char ch in strSurrogatesPair.ToCharArray()) { if (char.IsSurrogate(ch)) { // 破棄 } else { sb.Append(ch); } } textBox1.Text = sb.ToString(); ※ 前者は、存在チェックのみ、~ 後者は、文字の位置まで特定可能(∴削除も可能。)。 ※ また、上記の方法では、結合文字はチェックできない。 ***結合文字チェック [#ibd227e9] -現状、ハッキリした方法が無い。 --サロゲートペアや結合文字が含まれているか調べる .NET Tips C#, VB.NET~ http://dobon.net/vb/dotnet/string/issurrogatepair.html#section4~ 結合文字が含まれているか調べる~ >ただし、Marksカテゴリにすべての結合文字が含まれているか、~ そして、結合文字以外の文字が一切含まれていないかについては、はっきりしていません。 ***Lengthチェック [#j8e5c7d1] サロゲート ペア文字・結合文字は、 -通常のLengthチェックでは、2文字分として表示される。ただし、見た目の文字は1文字。 -また、プログラム中でのバイト表現(UTF-16)でのバイト長は、通常の文字が2バイトであるのに対し、4バイト。 サロゲート ペア文字・結合文字を含む文字列の見た目の文字列長を調べる場合は、 -System.Globalization名前空間のStringInfoクラスを使用する。 -string.Length、string.Substringなどは原則禁止(string.Lengthは、文字列のバイト長を調査する場合などは使用可能) -ただし、.NET Framework 1.1以前のランタイムでは、このクラスの仕様が異なり下記の様に利用できない。 /// <summary>文字列情報の表示</summary> /// <param name="strSurrogatesPair">文字列</param> private void GetStringInfo(string strSurrogatesPair) { // System.Globalization.StringInfoを使用する。 StringInfo si = new StringInfo(strSurrogatesPair); // 文字列を表示 MessageBox.Show(strSurrogatesPair); // 長さを表示1 MessageBox.Show("長さ(文字列長1):" + strSurrogatesPair.Length); // 長さを表示2 MessageBox.Show("長さ(文字列長2):" + si.LengthInTextElements); // 長さを表示3 MessageBox.Show("長さ(プログラム中(UTF-16)でのバイト長):" + Encoding.Unicode.GetBytes(strSurrogatesPair).Length); } -[参考]:MSDNライブラリ > .NET Frameworkクラス ライブラリ > StringInfoメンバ~ http://msdn.microsoft.com/ja-jp/library/system.globalization.stringinfo_members.aspx *可逆チェック [#s9e7f29f] エンコーディングを使用して可逆チェックをする。 特定のエンコーディングの -コードページ範囲内の文字であるか? -Unicodeからの双方向のエンコーディングか可能か? をチェックできる。 **例:MS932の範囲内であるか?のチェック [#nf743037] -以下のようにエンコーディングを行う。~ ++①Unicode文字列 ++→MS932エンコーディング ++→②MS932文字列(バイト配列) ++→MS932デコーディング ++→③Unicode文字列 -上記の結果から、~ ①Unicode文字列と、③Unicode文字列を比較し=か?をチェックする。 *サンプルコード [#z9673bbb] -JIS2k4Checker~ https://github.com/OpenTouryoProject/OpenTouryo/blob/develop/root/programs/C%23/Frameworks/Infrastructure/Public/Str/JIS2k4Checker.cs