タグ : バイト

 

.NET 文字列を指定されたバイト数に成型する

他システムと固定長ファイルで連携したり、帳票レイアウトのための位置調整など、「文字列を指定されたバイト数に成型する(かつ文字化けはさせない)」要件は意外と多いものです。
 
以前に投稿した「TruncateByteLeftメソッド」や「GetByteCountメソッド」などを組み合わせると、比較的簡単に成型することができます。
 
●左詰めで成型する場合
StringUtility utility = new StringUtility();

utility.FormFixedByteLengthLeft("1あいうえお", 4);
実行結果:”1あ¸”
 
●右詰めで成型する場合
StringUtility utility = new StringUtility();

utility.FormFixedByteLengthRight("1あいうえお", 4);
実行結果:”¸1あ”
 
実行結果の半角スペースは「¸」で表します。
上記例では切り詰める方向が左からですが、右から切り詰めるオーバーロードも用意しております。
 
以下のエリアではFormFixedByteLengthLeftメソッドとFormFixedByteLengthRightメソッドを実際に動かした時の挙動を確認できます。
 
StringUtility utility = new StringUtility();

utility.FormFixedByteLengthLeft(
    
 ", 
 );
実行結果:
“”
 
StringUtility utility = new StringUtility();

utility.FormFixedByteLengthRight(
    
 ", 
 );
実行結果:
“”
 
実行結果の半角スペースは「¸」で表します。
 
FormFixedByteLengthLeftメソッド、FormFixedByteLengthRightメソッドのソースコードは以下になります。
 
        /// <summary>
        /// 文字列を指定されたバイト長に左詰めで成型します
        /// </summary>
        /// <param name="target">対象の文字列</param>
        /// <param name="lengthByte">バイト長</param>
        /// <param name="padCharacter">パッドキャラクター</param>
        /// <param name="isTruncateLeft">文字列を左側から切り詰める場合はtrue、それ以外はfalse</param>
        /// <returns>指定されたバイト長に左詰めで成型された文字列</returns>
        /// <remarks>成型された文字列の先頭・末尾に全角文字途中の要素が混入している場合は除去し、パッドキャラクターを追加します</remarks>
        /// <remarks>Unicodeでバイト長に奇数が指定された場合などは、バイト長を超えない最大の長さで成型します</remarks>
        public string FormFixedByteLengthLeft(string target, int lengthByte,
            char padCharacter, bool isTruncateLeft)
        {
            // 部分文字列を取得
            string partialString = isTruncateLeft ? TruncateByteLeft(target, lengthByte) :
                TruncateByteRight(target, lengthByte);

            // パッドするバイト長を取得
            int padLengthByte = lengthByte - GetByteCount(partialString);

            // パッドする必要がない場合
            if (padLengthByte == 0)
            {
                return partialString;
            }

            // パッドする長さを取得
            int padLength = padLengthByte / GetByteCount(padCharacter.ToString());

            return partialString.PadRight(partialString.Length + padLength, padCharacter);
        }

        /// <summary>
        /// 文字列を指定されたバイト長に左詰めで成型します
        /// </summary>
        /// <param name="target">対象の文字列</param>
        /// <param name="lengthByte">バイト長</param>
        /// <param name="padCharacter">パッドキャラクター</param>
        /// <returns>指定されたバイト長に左詰めで成型された文字列</returns>
        /// <remarks>成型された文字列の末尾に全角文字途中の要素が混入している場合は除去し、パッドキャラクターを追加します</remarks>
        /// <remarks>Unicodeでバイト長に奇数が指定された場合などは、バイト長を超えない最大の長さで成型します</remarks>
        public string FormFixedByteLengthLeft(string target, int lengthByte,
            char padCharacter)
        {
            return FormFixedByteLengthLeft(target, lengthByte, padCharacter, true);
        }

        /// <summary>
        /// 文字列を指定されたバイト長に左詰めで成型します
        /// </summary>
        /// <param name="target">対象の文字列</param>
        /// <param name="lengthByte">バイト長</param>
        /// <returns>指定されたバイト長に左詰めで成型された文字列</returns>
        /// <remarks>成型された文字列の末尾に全角文字途中の要素が混入している場合は除去し、半角スペースを追加します</remarks>
        /// <remarks>Unicodeでバイト長に奇数が指定された場合などは、バイト長を超えない最大の長さで成型します</remarks>
        public string FormFixedByteLengthLeft(string target, int lengthByte)
        {
            return FormFixedByteLengthLeft(target, lengthByte, ’ ’);
        }

        /// <summary>
        /// 文字列を指定されたバイト長に右詰めで成型します
        /// </summary>
        /// <param name="target">対象の文字列</param>
        /// <param name="lengthByte">バイト長</param>
        /// <param name="padCharacter">パッドキャラクタ</param>
        /// <param name="isTruncateLeft">文字列を左側から切り詰める場合はtrue、それ以外はfalse</param>
        /// <returns>指定されたバイト長に右詰めで成型された文字列</returns>
        /// <remarks>成型された文字列の先頭・末尾に全角文字途中の要素が混入している場合は除去し、パッドキャラクターを追加します</remarks>
        /// <remarks>Unicodeでバイト長に奇数が指定された場合などは、バイト長を超えない最大の長さで成型します</remarks>
        public string FormFixedByteLengthRight(string target, int lengthByte,
            char padCharacter, bool isTruncateLeft)
        {
            // 部分文字列を取得
            string partialString = isTruncateLeft ? TruncateByteLeft(target, lengthByte) :
                TruncateByteRight(target, lengthByte);

            // パッドするバイト長を取得
            int padLengthByte = lengthByte - GetByteCount(partialString);

            // パッドする必要がない場合
            if (padLengthByte == 0)
            {
                return partialString;
            }

            // パッドする長さを取得
            int padLength = padLengthByte / GetByteCount(padCharacter.ToString());

            return partialString.PadLeft(partialString.Length + padLength, padCharacter);
        }

        /// <summary>
        /// 文字列を指定されたバイト長に右詰めで成型します
        /// </summary>
        /// <param name="target">対象の文字列</param>
        /// <param name="lengthByte">バイト長</param>
        /// <param name="padCharacter">パッドキャラクター</param>
        /// <returns>指定されたバイト長に右詰めで成型された文字列</returns>
        /// <remarks>成型された文字列の末尾に全角文字途中の要素が混入している場合は除去し、パッドキャラクターを追加します</remarks>
        /// <remarks>Unicodeでバイト長に奇数が指定された場合などは、バイト長を超えない最大の長さで成型します</remarks>
        public string FormFixedByteLengthRight(string target, int lengthByte,
            char padCharacter)
        {
            return FormFixedByteLengthRight(target, lengthByte, padCharacter, true);
        }

        /// <summary>
        /// 文字列を指定されたバイト長に右詰めで成型します
        /// </summary>
        /// <param name="target">対象の文字列</param>
        /// <param name="lengthByte">バイト長</param>
        /// <returns>指定されたバイト長に右詰めで成型された文字列</returns>
        /// <remarks>成型された文字列の末尾に全角文字途中の要素が混入している場合は除去し、半角スペースを追加します</remarks>
        /// <remarks>Unicodeでバイト長に奇数が指定された場合などは、バイト長を超えない最大の長さで成型します</remarks>
        public string FormFixedByteLengthRight(string target, int lengthByte)
        {
            return FormFixedByteLengthRight(target, lengthByte, ’ ’);
        }
 
 
Clipボタンをクリックすると、「StringUtility」というクラスがコピーされます。このソースを「StringUtility.cs」ファイルにコピーするとすぐご利用いただけます。
 

.NET 文字列を指定されたバイト数に切り詰める

VBのLeftBやRightBに相当するメソッドを作成しました。
 
以前に投稿した「SubstringByteメソッド」を使用しますので、切り詰めた部分文字列が文字化けする場合は、文字化けした文字を除去します。
 
●左から切り詰める場合
StringUtility utility = new StringUtility();

utility.TruncateByteLeft("1あいうえお", 4);
実行結果:”1あ”
 
●右から切り詰める場合
StringUtility utility = new StringUtility();

utility.TruncateByteRight("1あいうえお", 4);
実行結果:”えお”
 
以下のエリアではTruncateByteLeftメソッドとTruncateByteRightメソッドを実際に動かした時の挙動を確認できます。
 
StringUtility utility = new StringUtility();

utility.TruncateByteLeft(
    
 ", 
 );
実行結果:
“”
 
StringUtility utility = new StringUtility();

utility.TruncateByteRight(
    
 ", 
 );
実行結果:
“”
 
※実行結果の半角スペースは「¸」で表します。
 
TruncateByteLeftメソッド、TruncateByteRightメソッドのソースコードは以下になります。
 
        /// <summary>
        /// 文字列を指定されたバイト長に左側から切り詰めます
        /// </summary>
        /// <param name="target">対象の文字列</param>
        /// <param name="lengthByte">バイト長</param>
        /// <returns>指定されたバイト長に切り詰めた文字列</returns>
        /// <remarks>
        /// <para>文字列が指定されたバイト長に満たない場合は、成型せずに返します</para>
        /// <para>切り詰めた文字列の末尾に全角文字途中の要素が混入している場合は除去します</para>
        /// </remarks>
        public string TruncateByteLeft(string target, int lengthByte)
        {
            // 対象の文字列のバイト長が指定されたバイト長以下の場合
            if (GetByteCount(target) <= lengthByte)
            {
                return target;
            }

            return SubstringByte(target, 0, lengthByte);
        }

        /// <summary>
        /// 文字列を指定されたバイト長に右側から切り詰めます
        /// </summary>
        /// <param name="target">対象の文字列</param>
        /// <param name="lengthByte">バイト長</param>
        /// <returns>指定されたバイト長に切り詰めた文字列</returns>
        /// <remarks>
        /// <para>文字列が指定されたバイト長に満たない場合は、成型せずに返します</para>
        /// <para>切り詰めた文字列の先頭に全角文字途中の要素が混入している場合は除去します</para>
        /// </remarks>
        public string TruncateByteRight(string target, int lengthByte)
        {
            // 対象の文字列のバイト長を取得
            int targetByteCount = GetByteCount(target);

            // 対象の文字列のバイト長が指定されたバイト長以下の場合
            if (targetByteCount <= lengthByte)
            {
                return target;
            }

            return SubstringByte(target, targetByteCount - lengthByte, lengthByte);
        }
 
 
Clipボタンをクリックすると、「StringUtility」というクラスがコピーされます。このソースを「StringUtility.cs」ファイルにコピーするとすぐご利用いただけます。
 

.NET 文字列からバイト単位で部分文字列を取得する

C#、VB.NETで半角を1バイト、全角を2バイトとして、指定したバイト数の部分文字列を取得する、SubstringByteメソッドを作成しました。
 
SubstringByteメソッドに「対象の文字列」、「開始位置のバイト(0から始まるインデックス)」、「部分文字列のバイト数」を指定し実行すると部分文字列を取得できます。
 
StringUtility utility = new StringUtility();

utility.SubstringByte("1あいうえお", 2, 6);
実行結果:”いう”
 
上記のように指定すると「あ」の後ろ半分から「え」の前半分までの6バイトの部分文字列を対象とし、文字化けする最初と最後の文字を除去した「いう」を返します。
 
半角を1バイト、全角を2バイトは文字エンコーディングに「シフトJIS」を指定した場合ですが、「.NET 文字列のバイト数を取得する」と同様に他の文字エンコーディングにも対応しております。
 
以下のエリアではSubstringByteメソッドを実際に動かした時の挙動を確認できます。
 
StringUtility utility = new StringUtility();

utility.SubstringByte(
    
 ", 
 , 
 );
実行結果:
“”
 
※実行結果の半角スペースは「¸」で表します。
 
SubstringByteメソッドのソースコードは以下になります。
 
        /// <summary>
        /// 文字エンコーディング
        /// </summary>
        private Encoding _myEncoding = Encoding.GetEncoding("Shift_JIS");

        /// <summary>
        /// 文字エンコーディング
        /// </summary>
        public Encoding MyEncoding
        {
            get
            {
                return this._myEncoding;
            }
        }

        /// <summary>
        /// 文字列からバイト単位で部分文字列を取得します
        /// </summary>
        /// <param name="target">対象の文字列</param>
        /// <param name="startIndexByte">開始位置インデックスバイト</param>
        /// <param name="lengthByte">部分文字列のバイト数</param>
        /// <returns>文字列からバイト単位で取得した部分文字列</returns>
        public string SubstringByte(string target, int startIndexByte, int lengthByte)
        {
            if (startIndexByte < 0)
            {
                throw new ArgumentOutOfRangeException(
                    "開始位置インデックスバイトが0未満です。");
            }

            if (lengthByte < 0)
            {
                throw new ArgumentOutOfRangeException(
                    "部分文字列のバイト数が0未満です。");
            }

            // 対象の文字列をバイト配列にする
            byte[] targetBytes = MyEncoding.GetBytes(target);

            // 開始位置インデックスバイト+部分文字列のバイト数が文字列のバイト数を超える場合
            if (targetBytes.Length < startIndexByte + lengthByte)
            {
                throw new ArgumentOutOfRangeException("開始位置インデックスバイトまたは部分文字列のバイト数の指定に誤りがあります。");
            }

            // 対象の文字列からバイト単位で部分文字列を取得
            string partialString = MyEncoding.GetString(
                targetBytes, startIndexByte, lengthByte);

            // 先頭に全角文字途中の要素が混入している場合は除去
            partialString = TrimHeadHalfwayDoubleByteCharacter(
                partialString, target, targetBytes, startIndexByte);

            // 末尾に全角文字途中の要素が混入している場合は除去
            partialString = TrimEndHalfwayDoubleByteCharacter(
                partialString, target, targetBytes, startIndexByte, lengthByte);

            return partialString;
        }

        /// <summary>
        /// 先頭に全角文字途中の要素が混入している場合は除去します
        /// </summary>
        /// <param name="partialString">部分文字列</param>
        /// <param name="target">対象の文字列</param>
        /// <param name="targetBytes">対象の文字列のバイト配列</param>
        /// <param name="startIndexByte">開始位置インデックスバイト</param>
        /// <returns>先頭の全角文字途中の要素を除去した部分文字列</returns>
        private string TrimHeadHalfwayDoubleByteCharacter(
            string partialString, string target, byte[] targetBytes, int startIndexByte)
        {
            // 部分文字列が空の場合
            if (partialString == string.Empty)
            {
                return partialString;
            }

            // 開始位置の要素を含む部分文字列を取得
            string leftString = MyEncoding.GetString(targetBytes, 0, startIndexByte + 1);

            // 部分文字列の先頭要素が一致する場合
            if (target[leftString.Length - 1] == partialString[0])
            {
                return partialString;
            }

            // 先頭の全角文字途中の要素を除去
            return partialString.Substring(1);
        }

        /// <summary>
        /// 末尾に全角文字途中の要素が混入している場合は除去します
        /// </summary>
        /// <param name="partialString">部分文字列</param>
        /// <param name="target">対象の文字列</param>
        /// <param name="targetBytes">対象の文字列のバイト配列</param>
        /// <param name="startIndexByte">開始位置インデックスバイト</param>
        /// <param name="lengthByte">部分文字列のバイト数</param>
        /// <returns>末尾の全角文字途中の要素を除去した部分文字列</returns>
        private string TrimEndHalfwayDoubleByteCharacter(
            string partialString, string target, byte[] targetBytes, int startIndexByte,
            int lengthByte)
        {
            // 部分文字列が空の場合
            if (partialString == string.Empty)
            {
                return partialString;
            }

            // 最終要素を含む部分文字列を取得
            string leftString = MyEncoding.GetString(
                targetBytes, 0, startIndexByte + lengthByte);

            // 部分文字列の最終要素が一致する場合
            if (target[leftString.Length - 1] == partialString[partialString.Length - 1])
            {
                return partialString;
            }

            // 末尾の全角文字途中の要素を除去
            return partialString.Substring(0, partialString.Length - 1);
        }
 
 
Clipボタンをクリックすると、「StringUtility」というクラスがコピーされます。このソースを「StringUtility.cs」ファイルにコピーするとすぐご利用いただけます。
g h T
 26,263 Total Views