IndexOfのCompareOptions
CompareInfoのIndexOfで、CompareOptionsってどんな比較をしてるの?と思って試してみました。
注)buffには本当は15文字目から半角カナが含まれています。はてなでは半角カナが全角に置き換えられてしまいます。
注2)IndexOfのいじめ試験プログラムです。IndexOfのまともな使い方の例ではありません。
using System; using System.Globalization; namespace Siokoshou { public class GrepCount4 { const string keyword = "ドラエモン"; // 0 5 10 15 22 32 const string buff = "ドラエモンどらえもんドラえもんドラエモン ド ラ エ モ ン ドラえもん"; // const string keyword = "cool"; // 0 4 8 13 21 // const string buff = "coolCOOLcOoL c o o l Cool"; // const string keyword = "ss"; // const string buff = "\u00df"; // エスツェット // const string keyword = ""; // const string buff = ""; static void Test( CompareOptions opt ) { Console.WriteLine( opt ); CultureInfo ci = new CultureInfo( "ja-JP" ); int found = 0; int pos = 0; while ( 0 <= ( pos = ci.CompareInfo.IndexOf( buff, keyword, pos, opt ) ) ) { Console.Write( "{0}, ", pos ); found++; pos++; } Console.WriteLine( "{0}found: {1}{0}", Environment.NewLine, found ); } static void Main() { Test( CompareOptions.None ); Test( CompareOptions.Ordinal ); Test( CompareOptions.IgnoreKanaType ); Test( CompareOptions.IgnoreKanaType | CompareOptions.IgnoreSymbols ); Test( CompareOptions.IgnoreKanaType | CompareOptions.IgnoreSymbols | CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreWidth | CompareOptions.IgnoreCase ); Console.ReadLine(); } } }
実行結果:
None 0, found: 1 Ordinal 0, found: 1 IgnoreKanaType 0, 5, 10, 32, found: 4 IgnoreSymbols, IgnoreKanaType 0, 5, 10, 21, 22, 31, 32, found: 7 IgnoreCase, IgnoreNonSpace, IgnoreSymbols, IgnoreKanaType, IgnoreWidth 0, 5, 10, 15, 21, 22, 31, 32, found: 8
どうやら文字列の比較処理は、Unicodeの詳細な知識なしで使うと問題に出会いそうですね。
keywordとbuffのコメントアウトしてある例もお楽しみください。@IT会議室を参考にしました。
(追記:ちょっとコード訂正しました)
(さらに追記:コード追加しました)
UTF-16になれば単純な値の比較だけで文字の比較ができるかと思っていたけど、世界中の文字を相手にするってことはそうもいかないってことなのか…。が〜んと打ちのめされました。