C#(というか.Net)には、色々な文字列比較の方法があることを知っているだろうか?
あなたが普段何気なくやっている文字列比較は実は奥が深く、小文字や大文字の比較はもちろん、半角/全角やカタカナ/ひらがななど、日本語専用ど直球な文字列比較もできる。
今回は、そんな奥深い文字列比較の世界を案内しよう。
小文字と大文字を区別しないで比較する
まずは、ローマ字入力のあるソフトなりWebサービスだと結構使いドコロのありそうな、小文字と大文字を区別せずに比較する方法を紹介しよう。
作例は、”IAMLEGEND”と”iamlegend”を、二つの方法で比較するもの。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
var uppercaseText = "IAMLEGEND"; var lowercaseText = "iamlegend"; // This outputs Equals on Ordinal : False Console.WriteLine( "Equals on Ordinal : {0}", uppercaseText.Equals( lowercaseText, StringComparison.Ordinal)); // This outputs Equals on Ignore : True Console.WriteLine( "Equals on Ignore : {0}", uppercaseText.Equals( lowercaseText, StringComparison.OrdinalIgnoreCase)); |
コメントに書いた出力結果からわかるとおり、StringComparison.Ordinalを使うと、小文字と大文字は区別されて、StringComparison.OrdinalIgnoreCaseなら区別されずに比較される。
もし、大文字と小文字を区別しないで文字列の比較をしたいときはStringComparison.OrdinalIgnoreCaseを使えばいいというわけだ。
ちなみに、比較で使った”iamlegend”は、リチャード・マシスンの名作SF小説「I Am Legend」から来ているのはご存知のとおり。この小説を映画化した「アイ・アム・レジェンド」は、元はリドリー・スコットが監督する予定だったという。
最近、精力的に作品を作りまくっているリドリー・スコットは、個人的マイ・ベストSF小説「火星の人」を映画化した「オデッセイ」も監督する。先日、その公開日が決まったようで、今から胸がワクドキだ。
マット・デイモン、火星での奇跡に挑む『オデッセイ』公開日決定
原作の「火星の人」は、「月は無慈悲な夜の女王」などの、現実世界にもある道具をどう組み合わせてSFをやるかといった作品=ビルドSFものが好きならドハマりすること間違いなし。
現実世界で「火星の人」のようなことをしている人がいて、何と鉄鉱石からトースターを作っている。
「現実は、小説よりも奇なり」
半角と全角を区別しないで比較する
Webサービスの会員登録で多いのが、名前や住所の読み方を半角カナで入力させるもの。
普段半角カナなんて使わないものだから、あれが出てくる度に困っちゃうんだけれど、なんでなくならないんだろうか? どうも、「昔からそうだった」的な思考停止の匂いを感じる。やれやれ、僕はキーを打った(村上春樹かよ)
あまり使うケースはないかもしれないけれど、そんな半角文字と全角文字を比較する方法を紹介しよう。この方法を使えば、“ツタヤ”と”ツタヤ”が同じものだと判定できる。
まずは、全角と半角を無視して文字列比較をする拡張メソッドを用意する。
※もちろん、比較ができればいいわけだから各人のプロジェクトにおいては拡張メソッドでなくともOK
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public static bool IgnoreWidthEquals( this string source, string target) { var compareInfo = System.Globalization.CultureInfo.CurrentCulture.CompareInfo; var compareResult = compareInfo.Compare( target, source, System.Globalization.CompareOptions.IgnoreWidth); return compareResult == 0; } |
CompareInfo.Compare()を使い、比較対象と比較方法 CompareOptions.IgnoreWidth を渡している。
これだけで、半角と全角を無視して比較できるなんてお手軽すぎる。やったぜアンダース!
さて、この拡張メソッドを使ってみる。比較対象は “アイウエオ”と”アイウエオ”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
var wideWidthText = "アイウエオ"; var nallowWidthText = "アイウエオ"; // This outputs Equals on Ordinal Width : False Console.WriteLine( "Equals on Ordinal Width : {0}", wideWidthText.Equals( nallowWidthText, StringComparison.Ordinal)); // This outputs Equals on Ignore Width : True Console.WriteLine( "Equals on Ignore Width : {0}", wideWidthText.IgnoreWidthEquals( nallowWidthText)); |
通常のEqual()を使って比較に失敗することを確かめたあと、先ほどの拡張メソッドを使って半角と全角を無視できていることを確かめた。バッチリである。
カタカナとひらがなを区別しないで比較する
ここまでローカルな部分をサポートしてくれているのかと驚くのだけれど、.Netは、カタカナとひらがなを区別しないで比較することができる。
ちょっと前に、とある銀行振り込みをしたときのことなんだけど、振込人名をカタカナで入力しないといけないところをひらがなで入力してしまったことがある。そのまま振込処理は終わったのだけれど、翌日、銀行のオペレーターみたいな人から電話がかかってきて、「ひらがなでらっしゃいますが、カタカナの入力間違いですよね?」と確認された。
そんな、明らかに見たらわかろーもんことを確認してくることに驚き、思わず、「ら、らっしゃいます……」と答えた僕は相当アホっぽかったと思う
もし銀行のシステムにこの処理が組み込まれていれば……。ということで、カタカナとひらがなを区別せずに比較する方法を紹介する。
全角と半角を比較したときと同じく、まずは比較用の拡張メソッド IgnoreKanaEquals() を用意する。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public static bool IgnoreKanaEquals( this string source, string target) { var compareInfo = System.Globalization.CultureInfo.CurrentCulture.CompareInfo; var compareResult = compareInfo.Compare( target, source, System.Globalization.CompareOptions.IgnoreKanaType); return compareResult == 0; } |
全角/半角のときとほとんど同じで、違いはCompare()の第三引数がCompareOptions.IgnoreKanaTypeになっているところだけ。
“あいうえお”と”アイウエオ”を、この拡張メソッドを使って比較してみる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
var hiraganaText = "あいうえお"; var katakanaText = "アイウエオ"; // This outputs Equals on Ordinal Kana : False Console.WriteLine( "Equals on Ordinal Kana : {0}", hiraganaText.Equals( katakanaText, StringComparison.Ordinal)); // Equals on Ignore Kana : True Console.WriteLine( "Equals on Ignore Kana : {0}", hiraganaText.IgnoreKanaEquals( katakanaText)); |
無事にひらがなとカタカナの違いを無視できた。いや〜C#って、ほんといい言語ですね。(水野晴郎風)
One Response
[C# .Net] PC名や改行文字まで。あなたのことなら何でも知っているEnvironmentの使い方 | TOACH
[…] C#(.Net)の文字列比較が日本語に対応しすぎていて笑えたので、他の比較方法と併せて紹介する。 […]