Pytanie Jak sprawdzić, czy ciąg znaków zawiera podciąg w JavaScript?


Zwykle spodziewam się String.contains() metoda, ale wydaje się, że nie istnieje.

Jaki jest rozsądny sposób, aby to sprawdzić?


7436
2017-11-24 13:05


pochodzenie


Jest to łatwe dzięki metodzie indexOf, możesz zobaczyć tutorial indexOf i substring tutaj: dreamsyssoft.com/javascript-shell-scripting/... - Triton Man
możliwy duplikat Ciąg JQuery zawiera zaznaczenie - Saswat
możesz zobaczyć prędkość r.indexOf(s) !== -1; najszybciej niż inne. hayageek.com/javascript-string-contains - Sherali Turdiyev
Oto wzorzec dla najpopularniejszych metod sprawdzania, czy ciąg znaków jest w ciągu znaków: jsben.ch/#/o6KmH - EscapeNetscape
Film obejmujący najlepsze z poniższych opcji poniżej <5 minut, tutaj: youtube.com/watch?v=KENPi0xTgcE - ssmith


Odpowiedzi:


Oto lista aktualnych możliwości:

1. (ES6) includes-idź do odpowiedzi

var string = "foo",
    substring = "oo";
string.includes(substring);

2. ES5 i starsze indexOf

var string = "foo",
    substring = "oo";
string.indexOf(substring) !== -1;

String.prototype.indexOf zwraca pozycję ciągu w drugim ciągu znaków. Jeśli nie zostanie znaleziony, wróci -1.

3. search-idź do odpowiedzi

var string = "foo",
    expr = /oo/;
string.search(expr);

4. lodash obejmuje-idź do odpowiedzi

var string = "foo",
    substring = "oo";
_.includes(string, substring);

5. RegExp-idź do odpowiedzi

var string = "foo",
    expr = /oo/;  // no quotes here
expr.test(string);

6. Dopasuj-idź do odpowiedzi

var string = "foo",
    expr = /oo/;
string.match(expr);

Testy wydajności pokazują to indexOf może być najlepszym wyborem, jeśli chodzi o punkt, w którym liczy się prędkość.


11489
2017-12-30 04:23



@Steve indexOf zawsze zwraca liczbę, więc nie trzeba jej używać !==. Jeśli chcesz zapisać bajty, możesz użyć ~'foo'.indexOf('oo') która zwraca wartość truey, jeśli podłańcuch zostanie znaleziony, i wartość falsyfikacji (0) jeśli tak nie jest. - Mathias Bynens
Dla ciekawskich: w systemach dwupartyjnych wartość -1 jest reprezentowana w postaci binarnej jako wszystkie 1s (1111 1111 1111 1111 1111 1111 1111 1111 dla 32 bitów). Bitowa odwrotność (~) tego jest zerowa lub zerowa, a zatem falsy. Dlatego działa sztuczka z zawijasami, a jeśli muszę to powiedzieć, to całkiem źle. - Adam Tolley
@SebNilsson Zapomniałeś dołączyć ~ operator, który zasugerowałem w moim komentarzu. ~'hello'.indexOf('h'); // -1, which is truthy, ale ~'hello'.indexOf('x'); // 0, which is falsy. - Mathias Bynens
@ pramodc84 ten link odnosi się do Array obiekt indexOf metoda nie do String metoda obiektowa - gion_13
@NicolasBarbulesco Jestem przekonany, że wszyscy ludzie, którzy patrzą na mój kod, będą o tym wiedzieć [["\t\n 987654321e-400"]] === 0 to fałsz. Jestem o wiele mniej pewna, że ​​każdy, kto patrzy na mój kod, będzie o tym wiedział [["\t\n 987654321e-432"]] == 0 jest prawdziwy. - kybernetikos


Możesz łatwo dodać contains Metoda do String z tym stwierdzeniem:

String.prototype.contains = function(it) { return this.indexOf(it) != -1; };

Uwaga: zobacz komentarze poniżej, aby znaleźć uzasadniony argument za nieużywaniem tego. Moja rada: użyj własnego osądu.

Alternatywnie:

if (typeof String.prototype.contains === 'undefined') { String.prototype.contains = function(it) { return this.indexOf(it) != -1; }; }

823
2017-11-24 14:17



Nie modyfikuj obiektów, które nie są Twoją własnością. nczonline.net/blog/2010/03/02/... - zachleat
@zachleat, zrozumiałe w praktyce. Ale "foobar" .contains ("bar") byłby naprawdę przydatnym wyjątkiem od reguły. - ndbroadbent
Eh, moją preferencją byłoby przystosowanie mojego modelu mentalnego do JavaScript i skorzystanie z indexOf. Ułatwi zrozumienie kodu dla następnego JavaScriptera, który pojawi się i będzie musiał go przeczytać. - zachleat
if (typeof String.prototype.contains === 'undefined') { String.prototype.contains = function(it) { return this.indexOf(it) != -1; }; } - Pavel Hodek
I to jest preferowane, aby użyć tej funkcji, jeśli zamierzasz często używać tego rodzaju indexOf. @zachleat, nie zgodziłbym się, że użycie indexOf jest bardziej czytelne niż zawiera. Zawiera opisuje, co się dzieje, gdzie do niektórych indexOf() != -1 może nie być tak przejrzyste. Ale każdemu z nich, o ile jesteś konsekwentny. - smdrager


Problem z kodem polega na tym, że w JavaScript jest rozróżniana wielkość liter. Twoja metoda połączenia

indexof()

powinien być

indexOf()

Spróbuj naprawić i sprawdź, czy to pomaga:

if (test.indexOf("title") !=-1) {
    alert(elm);
    foundLinks++;
}

429
2018-01-07 10:23



@JeremyW, powiedziałbym w tym miejscu, że wartość tej odpowiedzi jest taka, że ​​ludzie, którzy popełnili ten sam błąd (indexof zamiast indexOf) może znaleźć tę odpowiedź i zobaczyć, co się dzieje. Nie dotknęłbym już tego pytania. - Victor


Tam jest string.includes w ES6:

"potato".includes("to");
> true

Uwaga może być konieczne załadowanie es6-shim lub podobnie, aby działało to w starszych przeglądarkach.

require('es6-shim')

361
2017-11-24 13:06



ponieważ byłem przyzwyczajony do "zawiera" w innych językach i po prostu zaimplementowałem moją funkcję, po prostu wpadłem na błąd. Krótkie informacje zwrotne na temat wsparcia. Firefox 19 - OSX => OK, Firefox 19 - Windows => NOK, Chrome - OSX, Windows => NOK - Patrick Hammer
Lubię to? String.prototype.contains = function (segment) { return this.indexOf(segment) !== -1; }; (BTW: Robienie rzeczy na prototypie jest złe) - Nijikokun
To nie jest wsparcie w chrome ..... :( - Krunal Patel
@Norris Jest w wersji ES6. Załaduj podkładkę ES6. Możesz go teraz użyć. - mikemaccana
.contains () i .includes () są eksperymentalne, re: niestandardowe. Nie polecałbym ich stosowania w systemach produkcyjnych. Na razie trzymałbym się z .indexOf (). - Mike S.


var index = haystack.indexOf(needle);

341
2018-03-05 09:53





Możesz użyć JavaScript search() metoda.

Składnia to: string.search(regexp)

Zwraca pozycję meczu lub -1, jeśli nie znaleziono żadnego dopasowania.

Zobacz przykłady: jsref_search

Nie potrzebujesz skomplikowanej składni wyrażeń regularnych. Jeśli nie znasz ich w prosty sposób st.search("title") zrobi. Jeśli chcesz, aby w teście było niewrażliwe na wielkość liter, powinieneś to zrobić st.search(/title/i).


237
2017-10-21 05:31



Wygląda na to, że byłaby wolniejsza niż funkcja indexOf, ponieważ musiałaby przeanalizować RegEx. Jeśli jednak chcesz, aby jakaś sprawa była niewrażliwa, twoja droga byłaby drogą do zrobienia (chyba), mimo że nie było to pytanie. Mimo że nie zadano mi tego, głosuję na to właśnie  bo opcji niewrażliwych na wielkość liter. - bgw
Nie prowadziłem testu porównawczego, ale zrobiłbym to str.toLowerCase().indexOf(searchstr.toLowerCase()) być bardziej wydajnym w przypadku wyszukiwania niewrażliwego na wielkość liter? - Tim S.
Z benchmarkem i okazuje się, że wyszukiwanie jest bardziej wydajne w przypadku wyszukiwania niewrażliwego na wielkość liter. jsperf.com/string-compare-perf-test Ale może być trudne korzystanie z wyszukiwania regex, ponieważ potrzebujesz uciec z niektórych znaków. - misaxi
Wyszukiwanie może prowadzić do błędów. Jak powiedział misaxi, musisz uciec z niektórych postaci. Używałem wyszukiwania nie zdając sobie sprawy, że parametr oczekiwał regex i szukałem znaku potoku. Jak się okazuje, dowolny ciąg .search ("|") == 0. - James Foster
Możesz użyć funkcji escapeRegExp, aby tekst podręczny był bezpieczny. function escapeRegExp(string){ return string.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1"); } od developer.mozilla.org/en/docs/Web/JavaScript/Guide/... - Mark


String.prototype.includes() został wprowadzony w ES6.

Określa, czy jeden ciąg znaków może znajdować się w innym ciągu,   w razie potrzeby zwracając wartość true lub false.

Składnia

var contained = str.includes(searchString [, position]);  

Parametry

searchString

Ciąg do wyszukania w tym ciągu.

position

Pozycja w tym ciągu znaków, od którego należy rozpocząć wyszukiwanie searchString domyślnie 0.

Przykład

var str = "To be, or not to be, that is the question.";

console.log(str.includes("To be"));    // true
console.log(str.includes("question")); // true
console.log(str.includes("To be", 1)); // false  

Uwaga

Może to wymagać podkładki ES6 w starszych przeglądarkach.


167
2018-05-29 07:46



FWIW połączona strona MDN ma prostą podkładkę / polyfill: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/... - Salman Abbas


Jeśli szukasz alternatywy do napisania brzydkiego testu -1, zamiast tego wstawiasz ~ tyldę.

if (~haystack.indexOf('needle')) alert('found');

Joe Zimmerman - zobaczysz, że użycie ~ na -1 powoduje konwersję na 0. Liczba 0 to a   wartość falsey, co oznacza, że ​​po konwersji skonwertuje wartość na false   a Boolean. Na pierwszy rzut oka może się to wydawać niezrozumiałe, ale   zapamiętaj funkcje takie jak indexOf zwrócą -1, gdy zapytanie nie jest   uznany. Oznacza to, że zamiast pisać coś podobnego do tego:

if (someStr.indexOf("a") >= 0) {
  // Found it
} else  {
  // Not Found
}

Możesz teraz mieć mniej znaków w swoim kodzie, abyś mógł go napisać   lubię to:

if (~someStr.indexOf("a")) {
  // Found it
} else  {
  // Not Found
}

Jeszcze szczegóły tutaj


120
2017-09-13 03:45



Tak, teraz wolałbym polecić polyfill standard ES6 includes() postępując zgodnie z tym: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/... - Christian Landgren


Ten kawałek kodu powinien działać dobrze:

var str="This is testing for javascript search !!!";
if(str.search("for") != -1) {
   //logic
} 

82
2017-12-13 20:05



wyszukuje przekazany znak lub słowo, jeśli zostanie znalezione, wówczas wyszukiwanie zwraca wartość całkowitą, która jest pozycją słowa w całym ciągu znaków. Jeśli słowo lub znak nie zostanie znaleziony, funkcja wyszukiwania zwraca -1. - vaibhav


Typowy sposób pisania a contains metoda w JavaScript jest:

if (!String.prototype.contains) {
    String.prototype.contains = function (arg) {
        return !!~this.indexOf(arg);
    };
}

Operator negacji bitowej (~) służy do zwrotu -1 w 0 (falsey), a wszystkie inne wartości będą niezerowe (prawda).

Operatory negacji podwójnej wartości boolowskiej są używane do rzutowania liczby na wartość logiczną.


77
2018-03-14 02:10



Jakie są zalety !!~ koniec >-1? - alex
@alex, Nie ma żadnej szczególnej przewagi poza tym, że nie polegasz na magicznych liczbach. Korzystaj z tego, z czym czujesz się dobrze. - zzzzBov
@zzzzBov! ~~ jest tak samo zależny od magicznej liczby -1 i faktu, że jej bitowa reprezentacja jest dopełnieniem 0. - Martijn
!!~this.indexOf(arg); nie jest łatwy do zrozumienia i nie jest tak jasny w kontekście, jak być musi. Przekazuje również informacje o tym fakcie ~-1 to 0, uzgodnione z @Martijn. Również jest wolniejsze niż proste porównanie z -1. Ale przejrzystość jest głównym czynnikiem. - babinik
@Nick, nigdy nie twierdziłem, że to był dobry sposób, po prostu powiedziałem, że to było pospolity droga. Jeśli chodzi o jasność, uważam, że jest to rozsądny sposób na zapisanie kilku bajtów dla biblioteki, ale mam tendencję do używania foo.indexOf('bar') > -1 - zzzzBov


W ES5

var s = "foo";
alert(s.indexOf("oo") > -1);

W ES6 istnieją trzy nowe metody: includes(), startsWith(), endsWith().

var msg = "Hello world!";

console.log(msg.startsWith("Hello"));       // true
console.log(msg.endsWith("!"));             // true
console.log(msg.includes("o"));             // true

console.log(msg.startsWith("o", 4));        // true
console.log(msg.endsWith("o", 8));          // true
console.log(msg.includes("o", 8));          // false


76
2017-11-24 13:13



wsparcie w3schools.com/jsref/jsref_endswith.asp - zloctb