방법: 문자열 비교(C# 프로그래밍 가이드)
문자열을 비교할 경우 한 문자열이 다른 문자열보다 크거나 작거나 같다는 결과를 얻게 됩니다.결과를 결정하는 규칙은 서수 비교를 수행하는지 문화권 구분 비교를 수행하는지에 따라 달라집니다.따라서 특정 작업에 올바른 비교를 사용하는 것이 중요합니다.
언어 규칙을 고려하지 않고 두 문자열 값을 비교하거나 정렬해야 하는 경우 기본 서수 비교를 사용합니다.기본 서수 비교(System.StringComparison.Ordinal)는 대/소문자를 구분합니다. 즉, 두 문자열의 각 문자가 서로 일치해야 합니다. 예를 들어 "and"는 "And"나 "AND"와 같지 않습니다.자주 사용하는 변형으로 System.StringComparison.OrdinalIgnoreCase가 있습니다. 이 경우에는 "and", "And" 및 "AND"가 일치합니다.StringComparison.OrdinalIgnoreCase는 파일 이름, 경로 이름, 네트워크 경로 및 사용자 컴퓨터의 로캘에 따라 값이 변경되지 않는 기타 문자열을 비교할 때 자주 사용됩니다.자세한 내용은 System.StringComparison을 참조하십시오.
일반적으로 문화권 구분 비교는 최종 사용자가 입력한 문자열을 비교하고 정렬할 때 사용됩니다. 이것은 이러한 문자열의 문자 및 정렬 규칙이 사용자 컴퓨터의 로캘에 따라 달라질 수 있기 때문입니다.현재 스레드의 문화권에 따라 동일한 문자를 포함하는 문자열도 다르게 정렬될 수 있습니다.
[!참고]
문자열을 비교할 경우 수행하려는 비교 종류를 명시적으로 지정하는 메서드를 사용해야 합니다.이렇게 하면 코드를 보다 쉽게 읽고 유지 관리할 수 있습니다.가능한 경우 수행할 비교의 종류를 지정할 수 있도록 StringComparison 열거형 매개 변수를 사용하는 System.String 및 System.Array 클래스의 메서드 오버로드를 사용해야 합니다.문자열을 비교할 때는 == 및 != 연산자를 사용하지 않는 것이 좋습니다.또한 String.CompareTo 인스턴스 메서드는 오버로드가 StringComparison을 사용하지 않으므로 사용하지 않는 것이 좋습니다.
예제
다음 예제에서는 사용자 컴퓨터의 로캘에 따라 값이 변경되지 않는 문자열을 올바르게 비교하는 방법을 보여 줍니다.또한 이 예제에서는 C#의 문자열 인터닝 기능을 보여 줍니다.프로그램이 둘 이상의 동일한 문자열 변수를 선언한 경우 컴파일러는 해당 변수를 모두 동일한 위치에 저장합니다.ReferenceEquals 메서드를 호출하면 두 문자열이 실제로 메모리의 동일한 개체를 참조한다는 것을 확인할 수 있습니다.인터닝을 방지하려면 다음 예제와 같이 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