Czy istnieje sposób, aby następujący zwrot był prawdziwy?
string title = "ASTRINGTOTEST";
title.Contains("string");
Wydaje się, że nie ma przeciążenia, które pozwala mi ustawić rozróżnianie wielkości liter. Obecnie UPPERCASE je oba, ale to po prostu głupie (przez co odnoszę się do problemów i18n , które są związane z obudową w górę iw dół).
AKTUALIZACJA
To pytanie jest starożytne i od tego czasu zdałem sobie sprawę, że poprosiłem o prostą odpowiedź na naprawdę obszerny i trudny temat, jeśli chcesz w pełni go zbadać.
W większości przypadków, w mono-językowej, bazy kod English to odpowiedź wystarczy. Podejrzewam, ponieważ większość osób przyjeżdżających tutaj należy do tej kategorii, jest to najpopularniejsza odpowiedź.
Ta odpowiedź rodzi jednak nieodłączny problem polegający na tym, że nie możemy porównać tekstu bez rozróżniania wielkości liter, dopóki nie dowiemy się, że oba teksty są tą samą kulturą i nie wiemy, czym jest ta kultura. To może być mniej popularna odpowiedź, ale myślę, że jest bardziej poprawna i dlatego oznaczyłem ją jako taką.
źródło
culture.CompareInfo.IndexOf(paragraph, word, CompareOptions.IgnoreCase) >= 0
? Wykorzystuje właściwą kulturę i nie rozróżnia wielkości liter, nie przydziela tymczasowych ciągów małych liter i pozwala uniknąć pytania, czy konwersja na małe litery i porównywanie jest zawsze takie samo jak porównanie bez rozróżniania wielkości liter.Możesz użyć metody String.IndexOf i podać
StringComparison.OrdinalIgnoreCase
jako typ wyszukiwania do użycia:Jeszcze lepsze jest zdefiniowanie nowej metody rozszerzenia ciągu:
Uwaga: propagacja zerowa
?.
jest dostępna od wersji C # 6.0 (VS 2015) w przypadku starszych wersjiSTOSOWANIE:
źródło
paragraph.ToLower(culture).Contains(word.ToLower(culture))
przypadkuCultureInfo.InvariantCulture
i nie rozwiązuje żadnych problemów z lokalizacją. Dlaczego zbyt skomplikować? stackoverflow.com/a/15464440/284795ToLower
wersja zawiera 2 przydziały, które nie są potrzebne w operacji porównywania / wyszukiwania. Po co niepotrzebnie alokować w scenariuszu, który tego nie wymaga?string
toIEnumerable<char>
stąd, że nie można go używać do znalezienia podciągistring.IndexOf(string)
jest użycie bieżącej kultury, podczas gdy domyślnym dlastring.Contains(string)
jest użycie porządkowego porównania. Jak wiemy, ten pierwszy można zmienić, wybierając dłuższe przeciążenie, a drugiego nie można zmienić. Konsekwencją tej niespójności jest następujący przykładowy kod:Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; string self = "Waldstrasse"; string value = "straße"; Console.WriteLine(self.Contains(value));/* False */ Console.WriteLine(self.IndexOf(value) >= 0);/* True */
Możesz użyć w
IndexOf()
ten sposób:Ponieważ 0 (zero) może być indeksem, sprawdzasz względem -1.
MSDN
źródło
Alternatywne rozwiązanie przy użyciu Regex:
źródło
RegexOptions.IgnoreCase & RegexOptions.IgnorePatternWhitespace & RegexOptions.CultureInvariant;
dla każdego, jeśli pomoże."."
w"This is a sample string that doesn't contain the search string"
. Lub spróbuj wyszukać"(invalid"
, jeśli o to chodzi.Regex.Escape
może pomóc. Regex nadal wydaje się niepotrzebny, gdyIndexOf
/ rozszerzenieContains
jest proste (i prawdopodobnie bardziej przejrzyste).Zawsze możesz najpierw po prostu zwiększyć lub zmniejszyć ciągi znaków.
Ups, właśnie widziałem ten ostatni kawałek. Porównywanie bez rozróżniania wielkości liter
*
prawdopodobnie*
i tak zrobiłoby to samo, a jeśli wydajność nie stanowi problemu, nie widzę problemu z tworzeniem dużych liter i porównywaniem ich. Mógłbym przysiąc, że raz widziałem porównanie bez rozróżniania wielkości liter ...źródło
Tylko .NET Core 2.0+ (od teraz)
.NET Core ma kilka metod radzenia sobie z tym od wersji 2.0:
Przykład:
Z czasem prawdopodobnie wejdą do standardu .NET, a stamtąd do wszystkich innych implementacji biblioteki klas podstawowych.
źródło
Jednym z problemów z odpowiedzią jest to, że zgłasza wyjątek, jeśli ciąg znaków ma wartość NULL. Możesz dodać to jako czek, aby nie:
źródło
if (string.IsNullOrEmpty(source)) return string.IsNullOrEmpty(toCheck);
Klasa StringExtension jest krokiem naprzód, połączyłem kilka powyższych postów, aby dać pełny przykład kodu:
źródło
StringComparison
?To jest czyste i proste.
źródło
fileNamestr
ma jakieś znaki specjalne regex (np*
,+
,.
, itd.), To będzie na dłuższą zaskoczenia. Jedynym sposobem, aby to rozwiązanie działało jak właściwaContains
funkcja, jest ucieczkafileNamestr
przez działanieRegex.Escape(fileNamestr)
.OrdinalIgnoreCase, CurrentCultureIgnoreCase czy InvariantCultureIgnoreCase?
Ponieważ tego brakuje, oto kilka zaleceń dotyczących tego, kiedy użyć którego:
Dos
StringComparison.OrdinalIgnoreCase
do porównań jako bezpiecznego domyślnego dopasowania łańcucha bez względu na kulturę.StringComparison.OrdinalIgnoreCase
porównań dla zwiększenia prędkości.StringComparison.CurrentCulture-based
operacji na łańcuchach podczas wyświetlania danych wyjściowych użytkownikowi.StringComparison.Ordinal
lubStringComparison.OrdinalIgnoreCase
gdy porównanie jestnieistotne językowo (na przykład symboliczne).
ToUpperInvariant
raczej niżToLowerInvariant
podczas normalizacji ciągów w celu porównania.Nie
StringComparison.InvariantCulture
łańcuchowych opartych na łańcuchach; jednym z nielicznych wyjątków byłyby
utrwalone pod względem językowym, ale kulturowo agnostyczne dane.
W oparciu o te zasady powinieneś używać:
mając na uwadze, że [TwojaDecyzja] zależy od powyższych zaleceń.
link do źródła: http://msdn.microsoft.com/en-us/library/ms973919.aspx
źródło
To są najprostsze rozwiązania.
Według indeksu
Zmieniając obudowę
Według Regex
źródło
Wiem, że to nie jest C #, ale w ramach (VB.NET) jest już taka funkcja
Wariant C #:
źródło
InStr
Metoda z VisualBasic montaż jest najlepszy, jeśli masz obawy dotyczące internacjonalizacji (lub można go reimplement). Patrząc w nim dotNeetPeek pokazuje, że uwzględnia nie tylko wielkie i małe litery, ale także typ kana i znaki o pełnej szerokości i połowie szerokości (dotyczy to głównie języków azjatyckich, chociaż istnieją również wersje alfabetu rzymskiego o pełnej szerokości) ). Pomijam niektóre szczegóły, ale sprawdź metodę prywatnąInternalInStrText
:źródło
Takie jak to:
źródło
Użyj tego:
źródło
Contains
nieCompare
.Contains
pomocąIndexOf
. To podejście jest równie pomocne! Przykład kodu C # na tej stronie używa string.Compare (). Wybór zespołu SharePoint, który jest!Jest to dość podobne do innego przykładu tutaj, ale zdecydowałem się uprościć wyliczanie bool, pierwotne, ponieważ inne alternatywy zwykle nie są potrzebne. Oto mój przykład:
A użycie jest coś takiego:
źródło
Korzystanie z RegEx jest prostym sposobem na to:
źródło
Aby skorzystać z odpowiedzi tutaj, możesz utworzyć metodę rozszerzenia ciągu znaków, aby uczynić ją nieco bardziej przyjazną dla użytkownika:
źródło
return CultureInfo.CurrentCulture.CompareInfo.IndexOf(paragraph, word, CompareOptions.IgnoreCase) >= 0;
zamiast tego.jeśli chcesz sprawdzić, czy przekazany ciąg jest ciągiem, istnieje prosta metoda.
Ta wartość logiczna zostanie zwrócona, jeśli ciąg znaków jest zawarty, czy nie
źródło
Tak proste i działa
źródło
źródło
Możesz użyć
string.indexof ()
funkcji. Będzie to bez rozróżniania wielkości literźródło
Sztuczka polega na tym, aby wyszukać ciąg znaków, ignorując wielkość liter, ale zachować dokładnie to samo (z tą samą literą).
Wyjście to „Reset”
źródło
źródło
Prosty sposób dla początkujących:
źródło