- 追加された行はこの色です。
- 削除された行はこの色です。
#blog2navi()
*C#:サロゲートペアを考慮した文字の列挙に foreach を使えるようにする [#b0061d58]
C#で文字列を1文字ずつ処理する場合、何も考えなければ次のような感じで書くと思います。
#code(csharp){{
string text = "あいうえお";
foreach (var c in text)
{
// c を処理する
}
}}
しかしこれだと文字列にサロゲートペア(4バイトで表されるUnicode文字)が含まれている場合に正常な処理が行えません。~
なのでサロゲートペアを考慮した列挙を行う場合は @code{System.Globalization.StringInfo}; クラスの静的メソッド @code{GetTextElementEnumerator}; を使って取得した @code{TextElementEnumerator}; オブジェクトを用いて処理することになります。
- [[文字列を1文字ずつ解析するには?(サロゲート文字対応)[C#、VB] − @IT>http://www.atmarkit.co.jp/fdotnet/dotnettips/732parsechars/parsechars.html]]
#code(csharp){{
string text = "あいうえお";
var e = StringInfo.GetTextElementEnumerator(text);
while (e.MoveNext())
{
string s = e.GetTextElement();
if (s.Length == 1)
{
// 通常文字を処理
char c = s[0];
}
else
{
// サロゲートペアを処理
}
}
}}
しかし私はこのメソッドを使うたびに思うのです。~
「@code{IEnumerator}; じゃなくて @code{IEnumerable}; なオブジェクトを返してくれよ!」と。~
なぜなら、そうすれば @code{foreach}; なり各種拡張メソッドなりが利用できるからです。
そういうわけでこんなクラスを作りました。
#code(csharp){{
using System;
using System.Collections;
using System.Globalization;
namespace ruche.util
{
/// <summary>
/// 文字列に対する TextElementEnumerator 列挙子を公開するクラス。
/// </summary>
public class TextElementEnumerable : IEnumerable
{
/// <summary>
/// コンストラクタ。
/// </summary>
/// <param name="source">列挙対象となる文字列。</param>
public TextElementEnumerable(string source)
{
this.Source = source;
}
/// <summary>
/// 列挙対象文字列を取得する。
/// </summary>
public string Source { get; private set; }
/// <summary>
/// TextElementEnumerator 列挙子を取得する。
/// </summary>
/// <returns>TextElementEnumerator 列挙子。</returns>
public TextElementEnumerator GetEnumerator()
{
return StringInfo.GetTextElementEnumerator(this.Source);
}
#region IEnumerable の明示的実装
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
#endregion
}
}
}}
このクラスを使えば次のように記述できます。
#code(csharp){{
string text = "あいうえお";
foreach (string s in new TextElementEnumerable(text))
{
if (s.Length == 1)
{
// 通常文字を処理
char c = s[0];
}
else
{
// サロゲートペアを処理
}
}
}}
すっきり!
RIGHT:Next: [[[C#:サロゲートペアを考慮した文字の列挙に拡張メソッドも使えるようにする>ぼやきごと/2013-03-15/C#:サロゲートペアを考慮した文字の列挙に拡張メソッドも使えるようにする]]]
RIGHT:Category: [[[プログラミング>ぼやきごと/カテゴリ/プログラミング]]][[[C#>ぼやきごと/カテゴリ/C#]]] - 2013-03-14 05:07:34
----
RIGHT:&blog2trackback();
#comment(above)
#blog2navi()