Jak przeprowadzić porównanie ciągów znaków bez rozróżniania wielkości liter w JavaScript?
javascript
string
Lecieć jak po sznurku
źródło
źródło
.localeCompare()
metodę javascript. Obsługiwane tylko przez nowoczesne przeglądarki w momencie pisania (IE11 +). patrz developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…"A".localeCompare( "a" );
powraca1
w konsoli Chrome 48."a"
pojawia się przed"A"
sortowaniem. Tak jak"a"
wcześniej"b"
. Jeśli takie zachowanie nie jest pożądane, można chcieć do.toLowerCase()
każdej litery / łańcucha. to znaczy."A".toLowerCase().localeCompare( "a".toLowerCase() )
patrz developer.mozilla.org/en/docs/Web/JavaScript/Reference/…===
sprawdzi równość, ale nie będzie wystarczająca do sortowania / porządkowania ciągów (por. pytanie, z którym pierwotnie się łączyłem).Odpowiedzi:
Najprostszym sposobem, aby to zrobić (jeśli nie martwisz się o znaki specjalne Unicode), jest wywołanie
toUpperCase
:źródło
if you're not worried about special Unicode characters
.toUpperCase
ponadtoLowerCase
?EDYCJA : Ta odpowiedź została pierwotnie dodana 9 lat temu. Dzisiaj powinieneś używać
localeCompare
zsensitivity: 'accent'
opcją:{ sensitivity: 'accent' }
MówilocaleCompare()
traktować dwa warianty tego samego listu bazowej jako taki sam , chyba że mają różne akcenty (jak w trzecim przykładzie) powyżej.Alternatywnie możesz użyć
{ sensitivity: 'base' }
, który traktuje dwie postacie jako równoważne, o ile ich podstawowy znak jest taki sam (więcA
byłoby traktowane jako równoważneá
).Pamiętaj, że trzeci parametr parametru
localeCompare
nie jest obsługiwany w przeglądarce IE10 lub nowszej lub w niektórych przeglądarkach mobilnych (zobacz tabelę kompatybilności na powyższej stronie), więc jeśli potrzebujesz obsługi tych przeglądarek, potrzebujesz pewnego rodzaju rezerwy:Oryginalna odpowiedź
Najlepszym sposobem na dokonanie porównania bez rozróżniania wielkości liter w JavaScript jest użycie
match()
metody RegExp zi
flagą.Wyszukiwanie bez rozróżniania wielkości liter
Gdy oba porównywane ciągi są zmiennymi (a nie stałymi), jest to nieco bardziej skomplikowane, ponieważ musisz wygenerować RegExp z ciągu, ale przekazanie ciągu do konstruktora RegExp może spowodować niepoprawne dopasowanie lub nieudane dopasowanie, jeśli ciąg ma specjalne wyrażenie regularne znaki w nim.
Jeśli dbasz o umiędzynarodowienie nie używać
toLowerCase()
albotoUpperCase()
jak nie dostarcza dokładnych case-niewrażliwe porównań we wszystkich językach.http://www.i18nguy.com/unicode/turkish-i18n.html
źródło
'a'.localeCompare('A')
i jak operacja szukam ciąg znaków bez rozróżniania wielkości liter.localeCompare
wersja wymaga, że silnik JavaScript obsługuje API ECMAScript® Internacjonalizacja , która jest nie wymagany robić. Dlatego zanim zaczniesz na nim polegać, możesz sprawdzić, czy działa w używanym środowisku. Na przykład:const compareInsensitive = "x".localeCompare("X", undefined, {sensitivity: "base"}) === 0 ? (a, b) => a.localeCompare(b, undefined, {sensitivity: "base"}) : (a, b) => a.toLowerCase().localeCompare(b.toLowerCase());
lub niektóre takie.Jak powiedziano w ostatnich komentarzach,
string::localeCompare
obsługuje porównania bez rozróżniania wielkości liter (między innymi ważnymi rzeczami).Oto prosty przykład
I ogólna funkcja, której możesz użyć
Zauważ, że zamiast tego
undefined
powinieneś prawdopodobnie wprowadzić określone ustawienia regionalne, z którymi pracujesz. Jest to ważne, jak wskazano w dokumentach MDNOpcje czułości
Obsługa przeglądarki
W chwili publikacji UC Browser dla Androida i Opera Mini nie obsługują ustawień regionalnych i parametrów opcji . Sprawdź https://caniuse.com/#search=localeCompare , aby uzyskać aktualne informacje.
źródło
Z pomocą wyrażeń regularnych możemy również osiągnąć.
/i
jest dla ignorowania wielkości liter. Jeśli nie jest to konieczne, możemy zignorować i przetestować pod kątem NIE rozróżniania wielkich i małych literźródło
keyWORD
zostanie wycięty, co spowoduje pozytywne dopasowanie. Ale ciągthis is a keyword yo
lubkeywords
spowoduje również pozytywne dopasowanie. Miej to na uwadze :-)/^keyword$/.test(source)
, ale 1) jeślikeyword
nie jest stałe, należy to zrobićnew RegExp('^' + x + '$').test(source)
i 2) odwołać się do wyrażenia regularnego w celu przetestowania czegoś tak prostego, jak równość ciągów bez rozróżniania wielkości liter wcale nie bardzo wydajny.Pamiętaj, że obudowa jest operacją zależną od ustawień regionalnych. W zależności od scenariusza możesz wziąć to pod uwagę. Na przykład, jeśli porównujesz nazwiska dwóch osób, możesz rozważyć ustawienia regionalne, ale jeśli porównujesz wartości generowane maszynowo, takie jak UUID, możesz tego nie zrobić. Dlatego używam następującej funkcji w mojej bibliotece utils (zauważ, że sprawdzanie typu nie jest uwzględnione ze względu na wydajność).
źródło
compareStrings("", "")
da,false
pomimo że łańcuchy są równe.true
dla mnie powraca . Być może jest to błąd przeglądarki?Niedawno utworzyłem mikro bibliotekę, która zapewnia pomocniki bez rozróżniania wielkości liter: https://github.com/nickuraltsev/ignore-case . (Wykorzystuje
toUpperCase
wewnętrznie.)źródło
jeśli martwisz się kierunkiem nierówności (być może chcesz posortować listę), prawie musisz przeprowadzić konwersję wielkości liter, a ponieważ w kodzie Unicode jest więcej małych liter niż wielkich liter, to prawdopodobnie najlepsza konwersja do użycia.
Wygląda na to, że JavaScript używa ustawień regionalnych „C” do porównywania ciągów, więc wynikowe uporządkowanie będzie brzydkie, jeśli ciągi zawierają inne niż litery ASCII. niewiele można z tym zrobić bez dokładniejszej kontroli napisów.
źródło
Załóżmy, że chcemy znaleźć zmienną
needle
łańcuchową w zmiennej łańcuchowejhaystack
. Istnieją trzy gotcha:string.toUpperCase
istring.toLowerCase
. Zamiast tego użyj wyrażenia regularnego, które ignoruje wielkość liter. Na przykład,var needleRegExp = new RegExp(needle, "i");
po którym następujeneedleRegExp.test(haystack)
.needle
. Uważaj, abyneedle
nie zawierało żadnych znaków specjalnych wyrażeń regularnych . Ucieczka za pomocąneedle.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
.needle
ihaystack
, po prostu ignorując"^"
wielkość liter, upewnij się, że dodajesz na początku i"$"
na końcu konstruktora wyrażeń regularnych.Biorąc pod uwagę punkty (1) i (2), przykładem może być:
źródło
new RegExp(...)
część w wierszu 3 następującym tekstemnew RegExp("^" + needle.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&") + "$", "i");
:. Dzięki temu nie będzie żadnych innych znaków przed ani za ciągiem wyszukiwanianeedle
.Istnieją dwa sposoby porównywania bez rozróżniania wielkości liter:
===
). Jak surowy operator traktuje operandy czytać rzeczy na: http://www.thesstech.com/javascript/relational-logical-operatorsUżyj metody „szukaj” w celu wyszukiwania bez rozróżniania wielkości liter. Przeczytaj o wyszukiwaniu i innych metodach ciągów na: http://www.thesstech.com/pattern-matching-using-string-methods
źródło
Tutaj jest wiele odpowiedzi, ale lubię dodawać rozwiązanie oparte na rozszerzeniu lib String:
W ten sposób możesz po prostu używać go tak jak w Javie!
Przykład:
Dane wyjściowe będą:
źródło
Użyj RegEx do dopasowania ciągu lub porównania.
W JavaScript możesz używać
match()
do porównywania ciągów, nie zapomnij wstawići
RegEx.Przykład:
źródło
matchString.match(/^test$/i)
.matchString.match(/x/i)
? Jeśli nie, co by zadziałało?źródło
Jeśli oba ciągi znaków mają takie same znane ustawienia narodowe, możesz chcieć użyć
Intl.Collator
obiektu takiego:Oczywiście możesz chcieć buforować
Collator
dla lepszej wydajności.Zaletą tego podejścia jest to, że powinno być znacznie szybsze niż użycie RegExps i opiera się na niezwykle konfigurowalnym (patrz opis
locales
ioptions
parametry konstruktora w powyższym artykule) zestawie gotowych do użycia kolektorów.źródło
accent
, że nie rozróżnia wielkości liter, ale traktujea
iá
jako osobne znaki. Tak więcbase
lubaccent
oba mogą być odpowiednie w zależności od dokładnych potrzeb.Napisałem rozszerzenie. bardzo trywialne
źródło
String#isEqual
lubObject#isEqual
natywnie wszystkie twoje strony zachowują się inaczej i mogą robić dziwne rzeczy, jeśli specyfikacja nie pasuje dokładnie do twojej.Nawet na to pytanie już udzielono odpowiedzi. Mam inne podejście do używania RegExp i dopasowywania, aby ignorować wielkość liter. Proszę zobaczyć mój link https://jsfiddle.net/marchdave/7v8bd7dq/27/
źródło
Co powiesz na NIE zgłaszanie wyjątków i NIE używanie powolnego wyrażenia regularnego?
Powyższy fragment zakłada, że nie chcesz dopasowywać, jeśli dowolny ciąg ma wartość NULL lub jest niezdefiniowany.
Jeśli chcesz dopasować wartość null / undefined, to:
Jeśli z jakiegoś powodu zależy Ci na niezdefiniowanym kontra zerowym:
źródło
str1 == str2 || ...
Ponieważ żadna odpowiedź nie zawierała prostego fragmentu kodu do użycia
RegExp
, oto moja próba:Ma kilka zalet:
undefined
na przykład, spowodowałby awarię wyrażenia podobnegostr1.toUpperCase()
).RegExp
ciągu.źródło
Jest to ulepszona wersja od tej odpowiedzi .
Zastosowania i testy:
Pokaż fragment kodu
źródło
Konwertuj oba na niższe (tylko raz ze względu na wydajność) i porównaj je z operatorem trójskładnikowym w jednym wierszu:
źródło
Jeśli wiesz, że masz do czynienia z
ascii
tekstem, możesz po prostu użyć porównania przesunięcia wielkich i małych liter.Upewnij się tylko, że ciąg „idealny” (ten, z którym chcesz się dopasować) jest pisany małymi literami:
źródło
Podoba mi się ta szybka stenografia -
Szybkie przetwarzanie i robi to, co jest przeznaczone.
źródło
To
javascript
biblioteka wydaje się zapewniać wiele operacji na łańcuchach znaków. Jest bardzo wygodny w użyciuJak zainstalować
Import
Ignoruj Porównaj ciąg
źródło