マイクロソフト系技術情報 Wiki」は、「Open棟梁Project」,「OSSコンソーシアム .NET開発基盤部会」によって運営されています。

目次

概要

文字チェックは、文字化け等を事前に防ぐために行われる。

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

範囲チェック

エンコード後に、範囲チェックをする。

JIS第1第2水準漢字チェック

仕様:

JIS第1第2水準漢字をチェックする

実装:

シフトJISのコード範囲でチェックを行う必要があるので、
一文字づつシフトJISにエンコード、数値型に変換し範囲チェックを行う。

サンプルコード:

//**********************************************************************************
//* 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の外字範囲チェック

仕様:

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)。

実装:

  • 一文字づつ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の外字でない。
        }
    }

個別チェック

コード表で連続しない文字をチェックする。

JIS2004チェック

追加文字チェック

  • 仕様:
    JIS2004で追加された文字をチェックする。
  • 実装:
    Unicodeのみに存在し、コード範囲もバラバラなので、
    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();

※ 前者は、存在チェックのみ、
  後者は、文字の位置まで特定可能(∴削除も可能。)。

※ また、上記の方法では、結合文字はチェックできない。

結合文字チェック

  • 現状、ハッキリした方法が無い。
    • サロゲートペアや結合文字が含まれているか調べる .NET Tips C#, VB.NET
      http://dobon.net/vb/dotnet/string/issurrogatepair.html#section4
      結合文字が含まれているか調べる

      ただし、Marksカテゴリにすべての結合文字が含まれているか、
      そして、結合文字以外の文字が一切含まれていないかについては、はっきりしていません。

Lengthチェック

サロゲート ペア文字・結合文字は、

  • 通常の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);
}

可逆チェック

エンコーディングを使用して可逆チェックをする。

特定のエンコーディングの

  • コードページ範囲内の文字であるか?
  • Unicodeからの双方向のエンコーディングか可能か?

をチェックできる。

例:MS932の範囲内であるか?のチェック

  • 以下のようにエンコーディングを行う。
    1. ①Unicode文字列
    2. →MS932エンコーディング
    3. →②MS932文字列(バイト配列)
    4. →MS932デコーディング
    5. →③Unicode文字列
  • 上記の結果から、
    ①Unicode文字列と、③Unicode文字列を比較し=か?をチェックする。

サンプルコード


Tags: :.NET開発, :国際化対応, :文字コード


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2018-06-14 (木) 17:30:29 (7d)