Порівняння рядків у C#
Однак це завдання ускладнюють фактори, що впливають на порівняння рядків:
- Ви можете вибрати порядкове чи лінгвістичне порівняння.
- Ви можете вказати, чи враховується регістр.
- Ви можете вибрати порівняння для конкретної мови та регіональних параметрів.
- Лінгвістичні порівняння залежать від мови та регіональних параметрів, а також від використовуваної платформи.
Полі System.StringComparison переліку представляють такі варіанти:
- CurrentCulture: порівняння рядків з використанням правил сортування з урахуванням мови та регіональних параметрів та поточної мови та регіональних параметрів.
- CurrentCultureIgnoreCase: порівнюйте рядки з використанням правил сортування з урахуванням мови та регіональних параметрів, поточної мови та регіональних параметрів та ігноруючи регістр порівнюваних рядків.
- InvariantCulture: порівняння рядків з використанням правил сортування з урахуванням мови та регіональних параметрів та інваріантної мови та регіональних параметрів.
- InvariantCultureIgnoreCase: порівнюйте рядки з використанням правил сортування з урахуванням мови та регіональних параметрів, інваріантної мови та регіональних параметрів та ігноруючи регістр порівнюваних рядків.
- Порядковий номер. Порівняння рядків за допомогою правил сортування порядкових (двійкових).
- OrdinalIgnoreCase: порівнюйте рядки з використанням правил сортування порядкових (двійкових) та ігноруючи регістр порівнюваних рядків.
Приклади C# у цій статті виконуються у вбудованому засобі виконання коду та на майданчику Try.NET. Натисніть кнопку Виконати, щоб виконати приклад у інтерактивному вікні. Після виконання коду ви можете змінити його та виконати змінений код, знову натиснувши кнопку Виконати. Або в інтерактивному вікні виконується змінений код або якщо компіляція завершується з помилкою, в інтерактивному вікні відображаються всі повідомлення про помилки компілятора C#.
При порівнянні рядків ви визначаєте їхній порядок.Порівняння використовують для сортування послідовності рядків. Після того, як послідовність знаходиться у відомому порядку, простіше шукати програмне забезпечення і для людей. Інші порівняння можуть бути перевірені, якщо рядки однакові. Такі ж перевірки схожі на рівність, але деякі відмінності, такі як відмінності у випадку, можуть ігноруватися.
Порядкові порівняння за умовчанням
Нижче наведені найпоширеніші операції за умовчанням:
- String.Equals
- String.Equality і String.Inequality, тобто оператори == рівності та != відповідно виконують регістр, порядкове порівняння. String.Equals має навантаження, в якому StringComparison можна надати аргумент для зміни правил сортування. Це показано в наступному прикладі:
string root = @ "C:\users"; string root2 = @ "C:\Users"; bool result = root.Equals(root2); Console.WriteLine($"Ordinal comparison: > and > are <(result ? "equal." : "not equal.")>"); result = root.Equals(root2, StringComparison.Ordinal); Console.WriteLine($"Ordinal comparison: > and > are <(result ? "equal." : "not equal.")>"); Console.WriteLine($"Using == says that > and > are <(root == root2 ? "equal" : "not equal")>");
За порядкових порівнянь рядків за умовчанням лінгвістичні правила не враховуються. Вони порівнюється двійкове значення кожного об'єкта Char у двох рядках. Таким чином, у порядковому порівнянні за умовчанням також враховується регістр.
Перевірка на рівність з допомогою String.Equals, і навіть операторів == і != відрізняється порівняння рядків з допомогою методів String.CompareTo і Compare(String, String). Усі вони виконують порівняння з урахуванням регістру. Однак, хоча тести на рівність виконують порядкове порівняння, CompareTo методи Compare та методи виконують лінгвістичне порівняння з урахуванням мови та регіональних параметрів за допомогою поточної мови та регіональних параметрів. Очистіть намір коду, викликавши навантаження, яке явно вказує тип порівняння для виконання.
Порядкові порівняння без урахування регістру
Цей метод String.Equals(String, StringComparison) дозволяє вказати StringComparison значення StringComparison.OrdinalIgnoreCase для нечутливого порядкового порівняння регістру. Існує також статичний метод String.Compare(String, String, StringComparison), який виконує нечутливе порядкове порівняння регістру, якщо вказати значення StringComparison.OrdinalIgnoreCase аргументу StringComparison . Ці порівняння показані в наступному коді:
string root = @ "C:\users"; string root2 = @ "C:\Users"; bool result = root.Equals(root2, StringComparison.OrdinalIgnoreCase); bool areEqual = String.Equals(root, root2, StringComparison.OrdinalIgnoreCase); int comparison = String.Compare(root, root2, comparisonType: StringComparison.OrdinalIgnoreCase); Console.WriteLine($"Ordinal ignore case: > and > are <(result ? "equal." : "not equal.")>"); Console.WriteLine($"Ordinal static ignore case: > and > are <(areEqual ? "equal." : "not equal.")>"); if (comparison < 0) Console.WriteLine($"> is less than >"); else if (comparison > 0) Console.WriteLine($"> is greater than >"); else Console.WriteLine($"> and > are equivalent in order");
Ці методи використовують угоди про регістр інваріантної мови та регіональних параметрів під час виконання нечутливого порядкового порівняння регістру.
Лінгвістичні порівняння
Багато методів порівняння рядків (наприклад String.StartsWith) використовують лінгвістичні правила для поточного мови та регіональних параметрів за замовчуванням для впорядкування вхідних даних. Це лінгвістичне порівняння іноді називається "порядком сортування слів". За виконання лінгвістичного порівняння деякі неелементні символи Юнікоду можуть мати спеціальні вагові значення. Наприклад, дефіс "-" може мати невелику вагу, призначену йому, щоб "co-op" і "coop" відображалися поруч один з одним у порядку сортування. Деякі недруковані символи керування можуть ігноруватися.Крім того, деякі символи Юнікод можуть бути еквівалентні послідовності екземплярів Char . У наступному прикладі використовується фраза "Вони танцюють на вулиці". У німецькій мові з "ss" (U+0073 U+0073) в одному рядку та "ß" (U+00DF) в іншому. Лінгвістично (у Windows) літери "ss" рівнозначні німецькому символу есцет "ß" у мовах "en-US" та "de-DE".
string first = "Sie tanzen auf der Straße."; string second = "Sie tanzen auf der Strasse."; Console.WriteLine($"First sentence is >"); Console.WriteLine($"Second sentence is >"); bool equal = String.Equals(first, second, StringComparison.InvariantCulture); Console.WriteLine($"The 2 strings <(equal == true ? "are" : "are not")>equal."); showComparison(first, second); string word = "coop"; string words = "co-op"; string other = "cop"; showComparison(word, words); showComparison(word, other); showComparison(words, other); void showComparison(string one, string two) < int compareLinguistic = String.Compare(one, two, StringComparison.InvariantCulture); int compareOrdinal = String.Compare(one, two, StringComparison.Ordinal); if (compareLinguistic < 0) Console.WriteLine($"> is less than > using invariant culture"); else if (compareLinguistic > 0) Console.WriteLine($"> is greater than > using invariant culture"); else Console.WriteLine($"> and > є equivalent in order using invariant culture"); if (compareOrdinal < 0) Console.WriteLine($"> is less than > using ordinal comparison"); else if (compareOrdinal > 0) Console.WriteLine($"> is greater than > using ordinal comparison"); else Console.WriteLine($"> and > є еквівалентним в order using ordinal comparison"); >
У Windows до .NET 5 порядок сортування "cop", "coop" та "co-op" змінюється при зміні лінгвістичного порівняння на порядкове порівняння. Дві пропозиції німецькою мовою також порівнюються по-різному при використанні різних типів порівняння. До .NET 5 API глобалізації .NET використовували бібліотеки національної підтримки мови (NLS).У .NET 5 і пізніших версіях API глобалізації .NET використовують міжнародні компоненти для бібліотек Юнікоду (ICU), які уніфікують. Поведінка глобалізації NET у всіх операційних системах, що підтримуються.
Порівняння з використанням певних мов та регіональних параметрів
У наступному прикладі зберігаються CultureInfo об'єкти для регіональних параметрів en-US та de-DE. Порівняння виконуються за допомогою об'єкта CultureInfo, щоб врахувати мову та регіональні параметри. Значення мови та регіональних параметрів, що використовуються, впливають на операції лінгвістичного порівняння. У наступному прикладі показані результати порівняння двох пропозицій німецькою з використанням мови та регіональних параметрів "en US" та "de-DE":
string first = "Sie tanzen auf der Straße."; string second = "Sie tanzen auf der Strasse."; Console.WriteLine($"First sentence is >"); Console.WriteLine($"Second sentence is >"); var en = new System.Globalization.CultureInfo("en-US"); // Для kultur-sensitive comparisons, use the String.Compare // overload that takes a StringComparison value.int i = String.Compare(first, second, en, System.Globalization.CompareOptions.None); Console.WriteLine($"Comparing in returns ."); var de = new System.Globalization.CultureInfo("de-DE"); i = String.Compare(first, second, de, System.Globalization.CompareOptions.None); Console.WriteLine($"Comparing in returns ."); bool b = String.Equals(first, second, StringComparison.CurrentCulture); Console.WriteLine($"The 2 strings <(b ? "are" : "are not")>equal."); string word = "coop"; string words = "co-op"; string other = "cop"; showComparison(word, words, en); showComparison(word, other, en); showComparison(words, other, en); void showComparison(string one, string two, System.Globalization.CultureInfo culture) < int compareLinguistic = String.Compare(one, two, en, System.Globalization.CompareOptions.None); int compareOrdinal = String.Compare(one, two, StringComparison.Ordinal); if (compareLinguistic < 0) Console.WriteLine($"> is less than > using en-US culture"); else if (compareLinguistic > 0) Console.WriteLine($"> is greater than > using en-US culture"); else Console.WriteLine($"> and > є еквівалентним в order using en-US culture"); if (compareOrdinal < 0) Console.WriteLine($"> is less than > using ordinal comparison"); else if (compareOrdinal > 0) Console.WriteLine($"> is greater than > using ordinal comparison"); else Console.WriteLine($"> and > є еквівалентним в order using ordinal comparison"); >
Порівняння з урахуванням мови та регіональних параметрів зазвичай використовуються для порівняння та сортування рядків, які вводять користувачі. Символи та правила сортування цих рядків можуть відрізнятися залежно від стандарту комп'ютера користувача. Навіть рядки, що містять ідентичні символи, можуть бути відсортовані по-різному, залежно від мови та регіональних параметрів потоку.
Лінгвістичне сортування та пошук рядків у масивах
Наведені нижче приклади показують, як сортувати та шукати рядки в масиві за допомогою лінгвістичного порівняння, що залежить від поточних значень мови та регіональних параметрів. Використовуйте статичні методи Array, які приймають параметр System.StringComparer.
У наступному прикладі показано, як сортувати масив рядків за допомогою поточної мови та регіональних параметрів:
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($" "); > Console.WriteLine("\n\rSorted order:"); // Specify Ordinal до demonstrate different behavior. Array.Sort(lines, StringComparer.CurrentCulture); foreach (string s in lines) < Console.WriteLine($" "); >
Після сортування масиву можна здійснити пошук записів за допомогою бінарного пошуку. Двійковий пошук починається з середини колекції, щоб визначити, яка половина колекції містить рядок, що шукається. Кожне подальше порівняння ділить частину колекції навпіл. Масив сортується за допомогою StringComparer.CurrentCulture. Локальна функція ShowWhere відображає відомості про те, де було знайдено рядок. Якщо рядок не знайдено, значення, що повертається вказує, де б воно знаходилося, якщо було б знайдено.
string[] lines = new string[] < @"c:\public\textfile.txt", @"c:\public\textFile.TXT", @"c:\public\Text.txt", @"c: \public\testfile2.txt">; Array.Sort(lines, StringComparer.CurrentCulture); string searchString = @"c:\public\TEXTFILE.TXT"; Console.WriteLine($"Binary search for >"); int result = Array.BinarySearch(lines, searchString, StringComparer.CurrentCulture); ShowWhere(lines, result); Console.WriteLine($" <(result >0 ? "Found" : "Did not find")> "); void ShowWhere(T[] array, int index) < if (index < 0) < index = ~index; Console.Write("Not found."Sorts between: "); якщо (index == 0) Console.Write("beginning of sequence and "); else Console.Write($"and "); якщо (index == array.Length) Console.WriteLine("end of sequence."); else Console.WriteLine($"."); > else < Console.WriteLine($"Found at index ." );
Порядкове сортування та пошук у колекціях
Наступний код використовує клас колекції System.Collections.Generic.List для зберігання рядків. Рядки сортуються за допомогою методу List.Sort. Цьому методу потрібен делегат, який порівнює та впорядковує два рядки. Метод String.CompareTo надає цю функцію порівняння. Запустіть приклад та стежте за порядком. Ця операція сортування використовує порядкове сортування з урахуванням регістру. Можна використати статичні методи String.Compare, щоб вказати різні правила порівняння.
List lines = new List < @"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($" "); > Console.WriteLine("\n\rSorted order:"); lines.Sort((left, right) => left.CompareTo(right)); foreach (string s in lines) < Console.WriteLine($" "); >
Після сортування за списком рядків можна здійснювати бінарний пошук. У наведеному нижче прикладі показано пошук у відсортованому списку за допомогою тієї ж функції порівняння. Локальна функція ShowWhere показує, де знаходиться або знаходився шуканий текст:
List lines = new List < @"c:\public\textfile.txt", @"c:\public\textFile.TXT", @"c:\public\Text.txt", @"c:\public\testfile2 .txt" >; lines.Sort((left, right) => left.CompareTo(right)); string searchString = @"c:\public\TEXTFILE.TXT"; Console.WriteLine($"Binary search for >"); int result = lines.BinarySearch(searchString); ShowWhere(lines, result); Console.WriteLine($" <(result >0 ? "Found" : "Did not find")> "); void ShowWhere(IList collection, int index) < if (index < 0) < index = ~index; Console.Write("Not found."Sorts between: "); якщо (index == 0) Console.Write("beginning of sequence and "); else Console.Write($"and "); якщо (index == collection.Count) Console.WriteLine("end of sequence."); else Console.WriteLine($"."); > else < Console.WriteLine($"Found at index ." );
Завжди використовуйте той самий тип порівняння для сортування та пошуку. Використання різних типів порівняння призводить до несподіваних результатів.
Див. також
Як відбувається порівняння рядків?
При порівнянні рядка розглядаються посимвольно ліворуч, при цьому порівнюються коди відповідних пар символів. Рядки рівні, якщо вони мають однакову довжину і символічно еквівалентні. У рядках різної довжини існуючий символ завжди більший за відповідний йому відсутній символ. Меншим буде той рядок, у якого менший код першого символу, що не збігається (незалежно від максимальних і поточних довжин порівнюваних рядків).
'abc' > 'ab' (true) 'abc' = 'abc' (true) 'abc' < 'abc' (false)
Подібні
Підписатися на стрічку
Для підписки на стрічку скопіюйте та вставте це посилання у вашу програму для читання RSS.
Site design/logo © 2024 Stack Exchange Inc; user contributions licensed under CC BY-SA . rev 2024.11.28.19452