Est-il une version de JavaScript de la Chaîne.indexOf() qui permet d'expressions régulières?
En javascript, est-il un équivalent de la Chaîne.indexOf() qui prend une expression régulière au lieu d'une chaîne de caractères pour le premier paramètre, tout en permettant un deuxième paramètre ?
J'ai besoin de faire quelque chose comme
str.indexOf(/[abc]/ , i);
et
str.lastIndexOf(/[abc]/ , i);
Alors Que Chaîne De Caractères.recherche() prend une regexp comme un paramètre qu'il ne me permet pas de spécifier un second argument!
Edit:
Ceci s'est avéré être plus difficile que je pensais j'ai donc écrit une petite fonction de test afin de tester toutes les solutions apportées... il suppose regexIndexOf et regexLastIndexOf ont été ajoutées à l'objet de type String.
function test (str) {
var i = str.length +2;
while (i--) {
if (str.indexOf('a',i) != str.regexIndexOf(/a/,i))
alert (['failed regexIndexOf ' , str,i , str.indexOf('a',i) , str.regexIndexOf(/a/,i)]) ;
if (str.lastIndexOf('a',i) != str.regexLastIndexOf(/a/,i) )
alert (['failed regexLastIndexOf ' , str,i,str.lastIndexOf('a',i) , str.regexLastIndexOf(/a/,i)]) ;
}
}
et je suis en train de tester comme suit pour vous assurer que, au moins pour un caractère regexp, le résultat est le même que si nous avons utilisé indexOf
//Recherche pour l'un parmi les emprisonne
test('xxx');
test('axx');
test('xax');
test('xxa');
test ("axa');
test('xaa');
test('aax');
test ("aaa");
|
à l'intérieur de[ ]
correspond au caractère littéral|
. Vous signifiait probablement[abc]
.- oui merci, vous avez raison, je vais le réparer, mais l'expression elle-même est sans importance...
- Mise à jour de ma réponse Pat, merci pour tous vos commentaires.
- J'ai trouvé un moyen plus simple et efficace est d'utiliser de la chaîne.match(/[A-Z]/). Si il n'y a pas de beaucoup, la méthode renvoie null, sinon vous obtiendrez un objet, vous pouvez le faire match(/[A-Z]/).indice pour obtenir l'index de la première lettre en majuscule
Vous devez vous connecter pour publier un commentaire.
Combinaison de quelques-uns des approches déjà mentionné (le indexOf est évidemment plutôt simple), je pense que ce sont les fonctions qui fera l'affaire:
Évidemment, la modification de la Chaîne intégrée de l'objet serait de les envoyer en place des drapeaux rouges pour la plupart des gens, mais cela peut être un moment où il n'est pas que les grandes d'un accord; il suffit d'en être conscient.
Mise à JOUR le: Édité
regexLastIndexOf()
c'est donc semble imiterlastIndexOf()
maintenant. S'il vous plaît laissez-moi savoir si il échoue toujours, et dans quelles circonstances.Mise à JOUR: il Passe tous les tests trouvés sur les dans les commentaires sur cette page, et de mon propre. Bien sûr, cela ne veut pas dire qu'il est à l'épreuve des balles. Tous les commentaires sont appréciés.
regexLastIndexOf
ne renvoie l'index de la dernière non-cumul match.regex.lastIndex = result.index + 1;
au lieu deregex.lastIndex = ++nextStop;
. Il va procéder pour le prochain match beaucoup plus rapide, espérons-le, sans perdre aucun résultat.Les Instances de la
String
constructeur ont une.recherche()
méthode qui accepte une RegExp et renvoie l'index du premier match.Pour lancer la recherche à partir d'une position particulière (pour simuler le deuxième paramètre de
.indexOf()
) vous pouvezslice
de la premièrei
caractères:Mais cette obtiendrez de l'index dans la chaîne plus courte (après la première partie a été coupé en tranches), de sorte que vous aurez envie d'ajouter ensuite la longueur de la coupé la partie (
i
) pour le retour de l'indice si ce n'était pas-1
. Cela vous donnera l'index dans la chaîne d'origine:function regexIndexOf(text, offset) { var initial = text.substr(offset).search(/re/); if(initial >= 0) { initial += offset; } return initial; }
J'ai une version courte pour vous. Il fonctionne bien pour moi!
Et si vous voulez une version prototype:
MODIFIER : si vous voulez ajouter le support pour fromIndex
Pour l'utiliser, aussi simple que cela:
startIndex
paramètre comme d'habitudeindeoxOf
etlastIndexOf
faire.startIndex
(oufromIndex
). Espérons que cela aide!lastIndexOfRegex
devrait également ajouter à la valeur defromIndex
pour le résultat.Utilisation:
Consultez la documentation ici.
0
, et a été posté... sept ans plus tard.Vous pouvez utiliser substr.
Basé sur BaileyP de réponse. La principale différence est que ces méthodes retournent
-1
si le motif ne peut être égalé.Edit: Merci à Jason Bunting la réponse que j'ai eu une idée. Pourquoi ne pas modifier le
.lastIndex
propriété de la regex? Bien que cela ne fonctionne que pour les modèles avec l'indicateur global (/g
).Edit: mis à Jour pour passer du cas de test.
Il n'intègre pas nativement, mais vous pouvez certainement ajouter cette fonctionnalité
Je n'ai pas bien tester ces méthodes, mais ils semblent si loin.
RexExp
instances ont un lastIndex bien déjà (si elles sont mondiales) et donc ce que je fais, c'est de la copie de l'expression régulière, en le modifiant légèrement pour les adapter à nos fins,exec
-ing sur la chaîne et en regardant lalastIndex
. Ce sera inévitablement plus rapide que la boucle sur la chaîne. (Vous avez suffisamment d'exemples de la manière de mettre cela sur la chaîne de prototype, à droite?),Vous pouvez également prototype les fonctions sur l'objet RegExp:
Une rapide explication de la façon dont je suis la modification de la
RegExp
: PourindexOf
je viens de veiller à ce que l'indicateur global est défini. PourlastIndexOf
de je suis à l'aide d'un négatif look-ahead pour trouver la dernière occurrence, à moins que leRegExp
était déjà correspondant à la fin de la chaîne.Après avoir toutes les solutions proposées échouer mes tests d'une manière ou l'autre, (edit: certains ont été mis à jour pour passer les tests après que j'ai écrit cela), j'ai trouvé la mozilla mise en œuvre pour Tableau.indexOf et Tableau.lastIndexOf
J'ai utilisé ces pour mettre en œuvre ma version de la Chaîne.le prototype.regexIndexOf et de la Corde.le prototype.regexLastIndexOf comme suit:
Ils semblent passer le test de fonctions que je fournis dans la question.
Évidemment, ils ne fonctionnent que si l'expression régulière correspond à un seul caractère, mais c'est suffisant pour mon usage étant donné que je vais l'utiliser pour des choses comme ( [abc] , \s , \W , \D )
Je vais garder le suivi de la question au cas où quelqu'un donne une meilleure/plus rapide/nettoyant/plus d'implémentation générique qui fonctionne sur n'importe quelle expression régulière.
J'avais besoin d'un
regexIndexOf
fonctionner aussi pour un tableau, j'ai donc programmé un moi-même. Cependant, je doute, que c'est optimisé, mais je suppose que cela devrait fonctionner correctement.Dans certains cas simples, vous pouvez simplifier votre recherche vers le haut en utilisant split.
Ce qui a un peu de problèmes graves:
Mais sur le côté positif, c'est beaucoup moins de code. La constante de longueur regex qui ne peuvent pas se chevaucher (comme
/\s\w/
pour trouver les limites de mot) c'est assez bon.De données avec peu de matches, à l'aide de la chaîne.la recherche est la plus rapide dans les navigateurs. Il re-tranches d'une chaîne à chaque itération :
Denses de données j'ai fait cela. Il est complexe par rapport à la méthode execute, mais à la densité des données, c'est 2 à 10 fois plus rapide que toutes les autres méthodes que j'ai essayé, et environ 100 fois plus rapide que la solution retenue. Les points principaux sont:
La nouvelle regex est exécuté et les résultats de soit que exec, ou la première exec, sont renvoyés;
jsPerf de méthodes
Je ne comprends pas le but des tests de haut. Les Situations qui nécessitent une regex sont impossibles à comparer à un appel à indexOf, qui, je pense, est le point de la méthode dans la première place. Pour obtenir le test à passer, il est plus logique d'utiliser 'xxx+(?!x)', que de régler la façon dont les regex itère.
Jason Bunting du dernier indice de la ne fonctionne pas. Le mien n'est pas optimal, mais il fonctionne.
Si vous êtes à la recherche pour un de très simple lastIndex de recherche avec les RegExp et ne se soucient pas si il imite lastIndexOf dans les moindres détails, cela peut attirer votre attention.
J'ai tout simplement d'inverser la chaîne, et de soustraire la première occurence de l'indice de longueur - 1. Il arrive à passer mon test, mais je pense qu'il pourrait se poser un problème de performance avec de longues cordes.
J'ai utilisé
String.prototype.match(regex)
qui retourne un tableau de chaînes de toutes les correspondances trouvées desregex
dans la chaîne (plus d'info voir ici):JS:
Bien, que vous êtes simplement à la recherche pour correspondre à la position d'un caractère , regex est peut-être exagéré.
Je présume que tout ce que vous voulez, au lieu de "rechercher le premier de ces ce personnage" , il suffit de trouver la première de ces caractères.
Bien sûr, cela est la réponse la plus simple, mais en fait ce que votre question vise à faire, mais sans la regex partie ( parce que vous n'avez pas de préciser pourquoi précisément ce devait être un regex )