方法 : 文字列を比較する (C# プログラミング ガイド)
文字列を比較すると、一方の文字列が他方の文字列よりも長いまたは短いという結果、または 2 つの文字列が等しいという結果が得られます。結果を決める規則は、序数の比較とカルチャに依存した比較のどちらを実行するかによって異なります。特定のタスクに対して正しい種類の比較を使用することが重要です。
言語規則に関係なく 2 つの文字列値を比較または並べ替える必要がある場合、基本序数比較を使用します。基本序数比較 (System.StringComparison.Ordinal) では、大文字と小文字が区別されます。したがって、2 つの文字列が文字レベルで一致している必要があります。たとえば、"and" と "And" または "AND" は等しくないと見なされます。このバリエーションが頻繁に使用される System.StringComparison.OrdinalIgnoreCase で、"and"、"And"、および "AND" が一致と見なされます。StringComparison.OrdinalIgnoreCase は、ファイル名、パス名、ネットワーク パスを比較するため、およびユーザーのコンピューターのロケールに基づき変更されない値を持つその他の文字列を比較するためによく使用されます。詳細については、「System.StringComparison」を参照してください。
カルチャに依存した比較は、通常、エンド ユーザーが入力した文字列を比較および並べ替えるために使用されます。これは、これらの文字列の文字および並べ替え規則が、ユーザーのコンピューターのロケールによって異なる場合があるためです。同じ文字を含む文字列でも、現在のスレッドのカルチャによっては異なった方法で並べ替えられる場合があります。
[!メモ]
文字列を比較する場合、実行する比較の種類を明示的に指定するメソッドを使用する必要があります。そのため、コードがより保守しやすくなり、またより読みやすくなります。実行する比較の種類を指定できるようにするために、できるだけ、StringComparison 列挙体のパラメーターを受け取る、System.String クラスおよび System.Array クラスのメソッドのオーバーロードを使用します。文字列を比較する場合、== 演算子および != 演算子の使用は避けるのが適切です。また、String.CompareTo インスタンス メソッドの使用も避けてください。これは、オーバーロードが StringComparison を受け取らないためです。
使用例
ユーザーのコンピューターのロケールに基づき値が変更される文字列を正確に比較する方法を、次の例に示します。また、C# の文字列インターン機能も示します。プログラムで 2 つ以上の同じ文字列変数を宣言すると、コンパイラはそれらをすべて同じ場所に保管します。ReferenceEquals メソッドを呼び出すことで、2 つの文字列がメモリ内の同じオブジェクトを実際に参照しているか確認できます。例に示されているように、インターンを避けるために String.Copy メソッドを使用してください。
// Internal strings that will never be localized.
string root = @"C:\users";
string root2 = @"C:\Users";
// Use the overload of the Equals method that specifies a StringComparison.
// Ordinal is the fastest way to compare two strings.
bool result = root.Equals(root2, StringComparison.Ordinal);
Console.WriteLine("Ordinal comparison: {0} and {1} are {2}", root, root2,
result ? "equal." : "not equal.");
// To ignore case means "user" equals "User". This is the same as using
// String.ToUpperInvariant on each string and then performing an ordinal comparison.
result = root.Equals(root2, StringComparison.OrdinalIgnoreCase);
Console.WriteLine("Ordinal ignore case: {0} and {1} are {2}", root, root2,
result ? "equal." : "not equal.");
// A static method is also available.
bool areEqual = String.Equals(root, root2, StringComparison.Ordinal);
// String interning. Are these really two distinct objects?
string a = "The computer ate my source code.";
string b = "The computer ate my source code.";
// ReferenceEquals returns true if both objects
// point to the same location in memory.
if (String.ReferenceEquals(a, b))
Console.WriteLine("a and b are interned.");
else
Console.WriteLine("a and b are not interned.");
// Use String.Copy method to avoid interning.
string c = String.Copy(a);
if (String.ReferenceEquals(a, c))
Console.WriteLine("a and c are interned.");
else
Console.WriteLine("a and c are not interned.");
// Output:
// Ordinal comparison: C:\users and C:\Users are not equal.
// Ordinal ignore case: C:\users and C:\Users are equal.
// a and b are interned.
// a and c are not interned.
StringComparison 列挙体を受け取る System.String メソッドを使用して文字列を比較する方法 (推奨されている方法) を、次の例に示します。ここでは、String.CompareTo インスタンス メソッドは使用しません。これは、オーバーロードが StringComparison を受け取らないためです。
// "They dance in the street."
// Linguistically (in Windows), "ss" is equal to
// the German essetz: 'ß' character in both en-US and de-DE cultures.
string first = "Sie tanzen in die Straße.";
string second = "Sie tanzen in die Strasse.";
Console.WriteLine("First sentence is {0}", first);
Console.WriteLine("Second sentence is {0}", second);
// Store CultureInfo for the current culture. Note that the original culture
// can be set and retrieved on the current thread object.
System.Threading.Thread thread = System.Threading.Thread.CurrentThread;
System.Globalization.CultureInfo originalCulture = thread.CurrentCulture;
// Set the culture to en-US.
thread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
// For culture-sensitive comparisons, use the String.Compare
// overload that takes a StringComparison value.
int i = String.Compare(first, second, StringComparison.CurrentCulture);
Console.WriteLine("Comparing in {0} returns {1}.", originalCulture.Name, i);
// Change the current culture to Deutch-Deutchland.
thread.CurrentCulture = new System.Globalization.CultureInfo("de-DE");
i = String.Compare(first, second, StringComparison.CurrentCulture);
Console.WriteLine("Comparing in {0} returns {1}.", thread.CurrentCulture.Name, i);
// For culture-sensitive string equality, use either StringCompare as above
// or the String.Equals overload that takes a StringComparison value.
thread.CurrentCulture = originalCulture;
bool b = String.Equals(first, second, StringComparison.CurrentCulture);
Console.WriteLine("The two strings {0} equal.", b == true ? "are" : "are not");
/*
* Output:
First sentence is Sie tanzen in die Straße.
Second sentence is Sie tanzen in die Strasse.
Comparing in current culture returns 0.
The two strings are equal.
*/
System.StringComparer パラメーターを受け取る静的 Array メソッドを使用したカルチャ依存の方法で、配列内の文字列を並べ替える方法および検索する方法を、次の例に示します。
class SortStringArrays
{
static void Main()
{
string[] lines = new string[]
{
@"c:\public\textfile.txt",
@"c:\public\textFile.TXT",
@"c:\public\Text.txt",
@"c:\public\testfile2.txt"
};
Console.WriteLine("Non-sorted order:");
foreach (string s in lines)
{
Console.WriteLine(" {0}", s);
}
Console.WriteLine("\n\rSorted order:");
// Specify Ordinal to demonstrate the different behavior.
Array.Sort(lines, StringComparer.Ordinal);
foreach (string s in lines)
{
Console.WriteLine(" {0}", s);
}
string searchString = @"c:\public\TEXTFILE.TXT";
Console.WriteLine("Binary search for {0}", searchString);
int result = Array.BinarySearch(lines, searchString, StringComparer.OrdinalIgnoreCase);
ShowWhere<string>(lines, result);
//Console.WriteLine("{0} {1}", result > 0 ? "Found" : "Did not find", searchString);
// Keep the console window open in debug mode.
System.Console.WriteLine("Press any key to exit.");
System.Console.ReadKey();
}
// Displays where the string was found, or, if not found,
// where it would have been located.
private static void ShowWhere<T>(T[] array, int index)
{
if (index < 0)
{
// If the index is negative, it represents the bitwise
// complement of the next larger element in the array.
index = ~index;
Console.Write("Not found. Sorts between: ");
if (index == 0)
Console.Write("beginning of array and ");
else
Console.Write("{0} and ", array[index - 1]);
if (index == array.Length)
Console.WriteLine("end of array.");
else
Console.WriteLine("{0}.", array[index]);
}
else
{
Console.WriteLine("Found at index {0}.", index);
}
}
}
/*
* Output:
Non-sorted order:
c:\public\textfile.txt
c:\public\textFile.TXT
c:\public\Text.txt
c:\public\testfile2.txt
Sorted order:
c:\public\Text.txt
c:\public\testfile2.txt
c:\public\textFile.TXT
c:\public\textfile.txt
Binary search for c:\public\TEXTFILE.TXT
Found at index 2.
*/
System.Collections.Hashtable、System.Collections.Generic.Dictionary<TKey, TValue>、System.Collections.Generic.List<T> などのコレクション クラスには、要素またはキーの型が string の場合に System.StringComparer パラメーターを受け取るコンストラクターがあります。通常は、これらのコンストラクターをできるだけ使用し、Ordinal または OrdinalIgnoreCase を指定する必要があります。
参照
関連項目
System.Globalization.CultureInfo