JavaScript: indexOf vs Match lors de la Recherche des Chaînes?
La lisibilité de côté, il y a aucune perceptibles écarts (de performance, peut-être) entre l'utilisation de
str.indexOf("src")
et
str.match(/src/)
Personnellement, je préfère match
(et regexp) mais les collègues semblent aller dans l'autre sens. Nous nous demandions si c'était ...?
EDIT:
J'aurais dit au début que c'est pour des fonctions qui feront partielle de la plaine-correspondance de chaîne (pour ramasser les identifiants dans les attributs de classe pour JQuery) plutôt que par des recherches à base de regexp avec des caractères génériques, etc.
class='redBorder DisablesGuiClass-2345-2d73-83hf-8293'
La différence entre:
string.indexOf('DisablesGuiClass-');
VS
string.match(/DisablesGuiClass-/)
- Je pense que
str.indexOf("xyz")
doit être comparé avec/xyz/.test(str)
- ici un indice de référence, ce qui se compare indexOf, regex et correspondre jsben.ch/#/r9hBp
- En fait
String.prototype.indexOf
est plus comparable àString.prototype.search
parce que les deux seront de retour l'index de début de la match. L'expression booléenne'foo'.indexOf('bar') !== -1
est mieux comparable à/bar/.test('foo')
parce que tous deux entraînent une valeur booléenne. Cela dit, pour de simples expressions sans les groupes et les ancrages de la performance devraient être comparables.str.match
est perdre en faire trop, car il renvoie à tous les matchs et je ne vous le conseille de l'utiliser pour des comparaisons.Cela dit, si vous n'avez pas de problème de performance choisi celui qui est plus lisible.
Vous devez vous connecter pour publier un commentaire.
RegExp est en effet plus lent que indexOf (vous pouvez le voir ici), mais normalement cela ne devrait pas être un problème. Avec RegExp, vous aussi, vous devez assurez-vous que la chaîne est correctement échappé, qui est un supplément de chose à penser.
De ces questions de côté, si les deux outils ne sont exactement ce dont vous avez besoin, pourquoi ne pas choisir le plus simple?
indexOf
moins que de nouvelles RegExp fonctionnalité est requise. Merci beaucoup! PS. Que configurable testpage vous avez accédé à votre réponse est cool - est-il mis à disposition du public d'une chose ou quelque chose de votre propre conception?'[\\?|&]'
devrait être[?&]
correspondre?
ou&
-- pas besoin d'un|
opérateur, ni de s'échapper de la?
.indexOf
est 12% plus lent que le regex match. Donc, avec beaucoup de choses, la bonne réponse est sans doute: Ça dépend.Votre comparaison ne peut pas être tout à fait juste.
indexOf
est utilisé avec plaine de chaînes de caractères et est donc très rapide;match
prend une expression régulière - bien sûr, il peut être plus lent en comparaison, mais si vous voulez faire une regex match, vous n'irez pas loin avecindexOf
. D'autre part, des moteurs d'expressions régulières peuvent être optimisés, et ont été l'amélioration de la performance dans les dernières années.Dans votre cas, si vous êtes à la recherche d'un verbatim de la chaîne,
indexOf
devrait être suffisant. Il y a toujours une demande pour les regexes, même si: Si vous avez besoin de faire correspondre ensemble mots et que vous voulez éviter les chaînes de correspondance, puis les expressions régulières vous donner "frontière de mot ancres". Par exemple:trouverez
bar
trois fois dansbar, fubar, barmy
, alors quene correspondent
bar
quand il ne fait pas partie d'un plus long terme.Comme vous pouvez le voir dans les commentaires, certaines comparaisons ont été faites qui montrent que d'une expression régulière peut être plus rapide que
indexOf
- si c'est la performance est critique, vous devrez peut-être le profil de votre code.indexOf
.indexOf
. Je viens de lancer jsperf.com/substring-test, et il affirme que "l'expression régulière insensible à la casse" est la manière la plus rapide et 30% plus rapide que le "indexOf", dont je refuse de croire.Si vous êtes à la recherche de sous-chaîne occurrences cas insensiblement puis
match
semble être plus rapide qu'une combinaison deindexOf
ettoLowerCase()
Vérifier ici - http://jsperf.com/regexp-vs-indexof/152
Ici toutes les façons possibles (relativement) à la recherche de chaîne de
//1. comprend (introduit dans l'ES6)
//2. chaîne de caractères.indexOf
//3. RegExp: test
//4. chaîne de caractères.match
//5. chaîne de caractères.recherche
Ici src: https://koukia.ca/top-6-ways-to-search-for-a-string-in-javascript-and-performance-benchmarks-ce3e9b81ad31
Repères semblent être tordu spécialement pour es6 comprend , lisez les commentaires.
En résumé:
si vous n'avez pas besoin de les matchs.
=> Soit vous avez besoin de regex et donc de l'utiliser test. Sinon es6 comprend ou indexOf. Encore test vs indexOf sont proches.
Et comprend vs indexOf:
Ils semblent être les mêmes : https://jsperf.com/array-indexof-vs-includes/4 (si c'était différent, il serait bizarre, ils effectuent principalement le même, sauf pour les différences qu'ils exposent cochez cette)
Et pour mon propre test de référence. ici, il est http://jsben.ch/fFnA0
Vous pouvez le tester (c'est le navigateur charge) [test plusieurs fois]
voici comment il a réalisé (terme multiples indexOf et comprend un battement à l'autre, et ils sont proches). Ils sont donc les mêmes. [ici, en utilisant la même plate-forme de test comme l'article ci-dessus].
Et ici pour le texte long version (8 fois plus)
http://jsben.ch/wSBA2
Testé chrome et firefox, même chose.
Avis jsben.ch ne gère pas de débordement de la mémoire (ou il y a des limites correctement. Elle ne montre aucun message) donc le résultat peut se tromper si vous ajoutez plus de 8 texte de la duplication (8 fonctionnent bien). Mais la conclusion est pour les très gros texte tous les trois de la même façon. Sinon pour faire court indexOf et comprend sont les mêmes et tester un peu plus lent. ou Peut être le même, car il ne semblait chrome (firefox 60 ans, il est plus lent).
Avis jsben.ch: pas de panique si vous obtenez incompatible résultat. Essayez différents temps et voir si elle est compatible ou pas. Changer de navigateur, parfois, ils se contentent d'exécuter totalement faux. Bug ou d'une mauvaise manipulation de la mémoire. Ou quelque chose.
ex:
Ici aussi ma référence sur la jsperf (mieux de détails et gérer des graphiques pour plusieurs navigateurs)
(en haut chrome)
texte normal
https://jsperf.com/indexof-vs-includes-vs-test-2019
résumé: comprend et indexOf ont même perofrmance. test plus lent.
(semblent tous les trois d'effectuer la même dans chrom)
Long texte (12 fois plus que la normale)
https://jsperf.com/indexof-vs-includes-vs-test-2019-long-text-str/
résumé: Tous les trois d'effectuer la même. (chrome et firefox)
très courte chaîne
https://jsperf.com/indexof-vs-includes-vs-test-2019-too-short-string/
résumé: comprend et indexOf effectuer la même et de tester plus lent.
Note: à propos de l'indice de référence ci-dessus. Pour le très courte chaîne version (jsperf) a eu une grosse erreur de chrome. Voir par mes yeux. autour de 60 échantillon a été exécuté pour les deux indexOf et inclut même façon répétée beaucoup de temps). Et de tester un peu moins et donc plus lent.
ne vous laissez pas berner avec le mauvais graphique. Il est clair que de mal. Même test ok pour firefox, sûrement c'est un bug.
Ici l'illustration: (la première image est le test sur firefox)
waaaa. Soudain indexOf est devenu superman. Mais comme je l'ai dit j'ai fait le test, et regardé le nombre d'échantillons, il était autour de 60. Les deux indexOf et comprend et ils ont fait la même. Un bug sur jspref. Sauf pour celui-ci (peut-être en raison d'un problème lié à la restriction de la mémoire) tout le reste est cohérent, il donnera plus de détails. Et vous voyez combien de simple lieu en temps réel.
Résumé Final
indexOf vs comprend => Même performance
test => peut être plus lente pour les chaînes courtes ou texte. Et même pour les longs textes. Et il un sens pour les frais généraux que le moteur d'expressions régulières ajouter. Dans google chrome, il semblait qu'il n'a pas d'importance du tout.
Vous demandez si
str.indexOf('target')
oustr.match(/target/)
doit être préféré. Comme d'autres affiches ont suggéré, les cas d'utilisation et les types de retour de ces méthodes sont différentes. Le premier demande: "où enstr
puis-je d'abord trouver'target'
?" La deuxième demande "nestr
correspondent à l'expression régulière et, dans l'affirmative, quels sont tous les matchs pour tout associé groupes de capture?"Le problème est que ni l'un, techniquement, est conçu pour poser la simple question "est ce que la chaîne de caractères contenant la sous-chaîne?" Il y a quelque chose qui est explicitement conçu pour le faire:
Il y a plusieurs avantages à utiliser
regex.test(string)
:str.match(/target/)
(et rivauxstr.indexOf('target')
)str
estundefined
ounull
, vous aurezfalse
(le résultat souhaité) au lieu de lancer unTypeError
À l'aide de
indexOf
devrait, en théorie, être plus rapide qu'une regex, quand vous êtes juste à la recherche pour certains de texte brut, mais vous devriez faire un peu de repères comparatifs vous-même si vous êtes préoccupé par la performance.Si vous préférez
match
et il est assez rapide pour vos besoins, alors aller pour elle.Pour ce que ça vaut, je suis d'accord avec vos collègues sur ce point: je ne l'utiliserais
indexOf
lors de la recherche d'une simple chaîne de caractères, et l'utilisationmatch
etc seulement quand j'ai besoin de la fonctionnalité supplémentaire fournie par des expressions régulières.Performance sage
indexOf
sera à tout le moins être légèrement plus rapide quematch
. Tout se résume à la mise en œuvre spécifique. Lorsque vous décidez de l'utiliser, posez-vous la question suivante:Les valeurs de retour sont différents
Côté de l'incidence sur les performances, qui sont traitées par d'autres réponses, il est important de noter que les valeurs de retour pour chaque méthode sont différents, de sorte que les méthodes ne peuvent pas simplement être remplacé, sans modifier votre logique.
Valeur de retour de
.indexOf
:integer
Valeur de retour de
.match
:array
Parce que
.indexOf
retourne0
si l'appel de la chaîne commence avec la valeur spécifiée, une simple truthy test échouera.Par exemple:
Compte tenu de cette classe...
...le retour de valeurs pour chaque serait différent:
vs
La bonne façon d'exécuter une truthy test avec le retour de
.indexOf
est à l'épreuve de contre-1
:toujours utiliser
indexOf
pour l'existence de sous-chaînes etmatch
uniquement lorsque vous en avez besoin. c'est à dire si vous avez été la recherche pour le motsrc
dans une chaîne qui peut également contenir desaltsrc
puisaString.match(/\bsrc\b/)
est en effet plus approprié.souviens d'Internet Explorer 8 ne comprennent pas
indexOf
.Mais si personne ne de vos utilisateurs utilise ie8 (google analytics vous dire) que d'omettre cette réponse.
solution possible pour résoudre ie8:
Comment fixer le Tableau indexOf() en JavaScript pour les navigateurs Internet Explorer