C#文字列の一部をバイト単位で取り出す (LeftB, MidB, RightB)

スポンサーリンク

旧システムなどの外部連携のために、テーブルに格納するデータにバイト制限をかける場合があります。良くあるのが、半角を 1 バイト、全角を 2 バイトでカウントして規定の長さに収めるなどです。

System.String クラスの Substring メソッドでは、文字単位でしか指定ができません。というよりは、半角または全角という概念は消滅しつつあります。(Unicode や UTF-8 の文字コードを参照)

VB6 では LeftB, MidB, RightB などの関数で、バイト単位での文字の取り出しができました。StrConv 関数などの合わせ技で文字コードを変えてから、使用していました。

半角は 1 バイト、全角は 2 バイトという考えは、Shift_JIS という文字コードの考えです。つまりは、Shift_JIS にエンコードしてやれば、半角 1 バイト、全角 2 バイトでのバイト数が取得できます。

System.Text.Encoding クラスから GetEncoding メソッドを実行し、ここで Shift_JIS の Encoding のインスタンスを取得します。そのインスタンスから、GetBytes メソッドを使用することで、Shift_JIS での文字コードを格納した System.Byte 型の配列ができます。この配列に対して、先の Encoding のインスタンスから GetString メソッド を使用し、どの位置から何バイトを System.String として返すかを指定できます。

サンプルコード

以下にサンプルコードを示します。

C# 全般
using System;

/// -----------------------------------------------------------------------------
/// <summary>
///     Microsoft.VisualBasic.Strings をカバーした静的クラスです。
/// <summary>
/// -----------------------------------------------------------------------------

public class VBStrings {

  #region LeftB メソッド

    /// -----------------------------------------------------------------------------------------
    /// <summary>
    ///     文字列の左端から指定したバイト数分の文字列を返します。</summary>
    /// <param name="stTarget">
    ///     取り出す元になる文字列。<param>
    /// <param name="iByteSize">
    ///     取り出すバイト数。</param>
    /// <returns>
    ///     左端から指定されたバイト数分の文字列。</returns>
    /// -----------------------------------------------------------------------------------------
    public static string LeftB(string stTarget, int iByteSize) {
        return MidB(stTarget, 1, iByteSize);
    }

  #endregion

  #region MidB メソッド (+1)

    /// -----------------------------------------------------------------------------------------
    /// <summary>
    ///     文字列の指定されたバイト位置以降のすべての文字列を返します。</summary>
    /// <param name="stTarget">
    ///     取り出す元になる文字列。</param>
    /// <param name="iStart">
    ///     取り出しを開始する位置。</param>
    /// <returns>
    ///     指定されたバイト位置以降のすべての文字列。</returns>
    /// -----------------------------------------------------------------------------------------
    public static string MidB(string stTarget, int iStart) {
        System.Text.Encoding hEncoding = System.Text.Encoding.GetEncoding("Shift_JIS");
        byte[] btBytes = hEncoding.GetBytes(stTarget);

        return hEncoding.GetString(btBytes, iStart - 1, btBytes.Length - iStart + 1);
    }

    /// -----------------------------------------------------------------------------------------
    /// <summary>
    ///     文字列の指定されたバイト位置から、指定されたバイト数分の文字列を返します。</summary>
    /// <param name="stTarget">
    ///     取り出す元になる文字列。</param>
    /// <param name="iStart">
    ///     取り出しを開始する位置。</param>
    /// <param name="iByteSize">
    ///     取り出すバイト数。</param>
    /// <returns>
    ///     指定されたバイト位置から指定されたバイト数分の文字列。</returns>
    /// -----------------------------------------------------------------------------------------
    public static string MidB(string stTarget, int iStart, int iByteSize) {
        System.Text.Encoding hEncoding = System.Text.Encoding.GetEncoding("Shift_JIS");
        byte[] btBytes = hEncoding.GetBytes(stTarget);

        return hEncoding.GetString(btBytes, iStart - 1, iByteSize);
    }

  #endregion

  #region RightB メソッド

    /// -----------------------------------------------------------------------------------------
    /// <summary>
    ///     文字列の右端から指定されたバイト数分の文字列を返します。</summary>
    /// <param name="stTarget">
    ///     取り出す元になる文字列。</param>
    /// <param name="iByteSize">
    ///     取り出すバイト数。</param>
    /// <returns>
    ///     右端から指定されたバイト数分の文字列。</returns>
    /// -----------------------------------------------------------------------------------------
    public static string RightB(string stTarget, int iByteSize) {
        System.Text.Encoding hEncoding = System.Text.Encoding.GetEncoding("Shift_JIS");
        byte[] btBytes = hEncoding.GetBytes(stTarget);

        return hEncoding.GetString(btBytes, btBytes.Length - iByteSize, iByteSize);
    }

  #endregion

}

使用例は以下のようになります。

C# 全般
    // 必要な変数を宣言する
    string stTarget = "ABCDEF";

    // 左端から 6 バイトの文字列を取得する
    MessageBox.Show(VBStrings.LeftB(stTarget, 6));        //ABCD

    // 左端から 4 バイト以降のすべての文字列を取得する
    MessageBox.Show(VBStrings.MidB(stTarget, 4));         //CDEF

    // 左端から 4 バイト目から 5 バイトの文字列を取得する
    MessageBox.Show(VBStrings.MidB(stTarget, 4, 5));      //CDE

    // 右端から 3 バイトの文字列を取得する
    MessageBox.Show(VBStrings.RightB(stTarget, 3));       //EF

関連するリファレンス

準備中です。

スポンサーリンク