.NET 日本語を用いる場合の複合書式設定について
2005年5月25日 コンピュータ コメント (1)(diarynoteでは<pre>が使えないようなので、連続した半角スペースが削除されてしまうため、以下では"_"で代用している。またブラウザでは表示がずれる。さらに"<"">"の半角もダメなようなので全角で記している・・・なんとかならんものか)
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/cpguide/html/cpconCompositeFormatting.asp
この文章中にあるAlighmentを使えば、.NET Frameworkを用いる場合に、たとえば文字列をテキストボックスなどに出力する際の書式を整えることが出来る。
以下C#を例に考える。
こうすることで以下のように出力されるようになる。
これで大丈夫、といいたいところだが、実は仕様なのかバグなのかこの複合書式設定には妙な動作がある。それは日本語などのいわゆる2バイト文字(全角文字)を入力した場合による。
先の例でfullNameへ代入した部分を以下のように変更する
こうすると出力は以下のようになる。
これは.NET内部では文字にUnicodeを用いているため、全角文字だろうと半角だろうと長さが1として扱われているためである。
これを解消するにはいくつか方法が考えられるが、最も簡単なのは余分な空白を削除してしまうことである。
if文は整列の幅を超えた場合は空白が入ることがないので、その場合を除いているだけである。
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/cpguide/html/cpconCompositeFormatting.asp
この文章中にあるAlighmentを使えば、.NET Frameworkを用いる場合に、たとえば文字列をテキストボックスなどに出力する際の書式を整えることが出来る。
以下C#を例に考える。
struct FullName{
public string Name;
public string Family;
public FullName(string name, string family)
{
Name = name;
Family = family;
}
}
FullName [] fullName = new FullName[2];
fullName[0] = new FullName("Kou", "Kirishima");
fullName[1] = new FullName("Estelle", "Branche");
foreach( FullName fn in fullName)
{
string str = String.Format("|Name = {0,8}, Family = {0,12}|", fn.Name, fn.Family);
Console.WriteLine(str);
}
こうすることで以下のように出力されるようになる。
|Name = Kou_____, Family = Kirishima___|
|Name = Estelle_, Family = Branche_____|
これで大丈夫、といいたいところだが、実は仕様なのかバグなのかこの複合書式設定には妙な動作がある。それは日本語などのいわゆる2バイト文字(全角文字)を入力した場合による。
先の例でfullNameへ代入した部分を以下のように変更する
FullName [] fullName = new FullName[3];
fullName[0] = new FullName("Kou", "Kirishima");
fullName[1] = new FullName("Estelle", "Branche");
fullName[2] = new FullName("高", "霧島");
こうすると出力は以下のようになる。
|Name = Kou_____, Family = Kirishima___|
|Name = Estelle_, Family = Branche_____|
|Name = 高_______, Family = 霧島__________|
これは.NET内部では文字にUnicodeを用いているため、全角文字だろうと半角だろうと長さが1として扱われているためである。
これを解消するにはいくつか方法が考えられるが、最も簡単なのは余分な空白を削除してしまうことである。
struct FullName{
public string Name;
public string Family;
public FullName(string name, string family)
{
Name = name;
Family = family;
}
public string [] JpnNameLength
{
get
{
System.Text.RegularExpressions.Regex re =
new System.Text.RegularExpressions.Regex(
"[^a-zA-Z 0-9]" ,
System.Text.RegularExpressions.RegexOptions.Singleline);
System.Text.RegularExpressions.MatchCollection mts1 = re.Matches(Name);
System.Text.RegularExpressions.MatchCollection mts2 = re.Matches(Family);
int [] counts = new int[]{mts1.Count, mts2.Count};
}
}
}
FullName [] fullName = new FullName[3];
fullName[0] = new FullName("Kou", "Kirishima");
fullName[1] = new FullName("Estelle", "Branche");
fullName[2] = new FullName("高", "霧島");
foreach( FullName fn in fullName)
{
string str = String.Format("|Name = {0,8}, Family = {0,12}|", fn.Name, fn.Family);
int[] jpncount = fn.JpnNameLength;
if(fn.Name.Length <=8)
sf = sf.Remove("|Name = ".Length + str.Name.Length, jpncount[0]);
if(fn.Family.Length <=12)
sf = sf.Remove("|Name = ".Length + str.Name.Length + ", Family = ".Length + str.Family.Length, jpncount[1]);
Console.WriteLine(str);
}
if文は整列の幅を超えた場合は空白が入ることがないので、その場合を除いているだけである。
コメント