[[Open棟梁Project>http://opentouryo.osscons.jp/]] - [[マイクロソフト系技術情報 Wiki>http://techinfoofmicrosofttech.osscons.jp/]]

-[[戻る>文字コード]]

* 目次 [#m402c4a9]
#contents

*概要 [#e675a56e]
文字チェックは、文字化け等を事前に防ぐために行われる。

以下の文字チェック・ルーチンが一般的である。

*エンコード後、範囲チェック [#v36f5f1c]
*範囲チェック [#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

***サンプルコード [#z9673bbb]
-JIS2k4Checker~
https://github.com/OpenTouryoProject/OpenTouryo/blob/develop/root/programs/C%23/Frameworks/Infrastructure/Public/Str/JIS2k4Checker.cs
*可逆チェック [#s9e7f29f]
エンコーディングを使用して可逆チェックをする。

*エンコーディングを使用したチェック [#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


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS