- 2015/1/18 06:21
C#、VB.NETで半角を1バイト、全角を2バイトとして、指定したバイト数の部分文字列を取得する、SubstringByteメソッドを作成しました。
SubstringByteメソッドに「対象の文字列」、「開始位置のバイト(0から始まるインデックス)」、「部分文字列のバイト数」を指定し実行すると部分文字列を取得できます。
StringUtility utility = new StringUtility();
utility.SubstringByte("1あいうえお", 2, 6);
実行結果:”いう”
上記のように指定すると「あ」の後ろ半分から「え」の前半分までの6バイトの部分文字列を対象とし、文字化けする最初と最後の文字を除去した「いう」を返します。
半角を1バイト、全角を2バイトは文字エンコーディングに「シフトJIS」を指定した場合ですが、「.NET 文字列のバイト数を取得する」と同様に他の文字エンコーディングにも対応しております。
以下のエリアでは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」ファイルにコピーするとすぐご利用いただけます。