J'essaie d'analyser le type de chaîne suivant:
[key:"val" key2:"val2"]
où il y a des paires clé arbitraire: "val" à l'intérieur. Je veux saisir le nom de la clé et la valeur. Pour les curieux, j'essaye d'analyser le format de la base de données de task warrior.
Voici ma chaîne de test:
[description:"aoeu" uuid:"123sth"]
qui vise à souligner que tout peut être dans une clé ou une valeur en dehors de l'espace, aucun espace autour des deux-points et les valeurs sont toujours entre guillemets.
Dans node, voici ma sortie:
[deuteronomy][gatlin][~]$ node
> var re = /^\[(?:(.+?):"(.+?)"\s*)+\]$/g
> re.exec('[description:"aoeu" uuid:"123sth"]');
[ '[description:"aoeu" uuid:"123sth"]',
'uuid',
'123sth',
index: 0,
input: '[description:"aoeu" uuid:"123sth"]' ]
Mais description:"aoeu"
correspond également à ce modèle. Comment puis-je récupérer tous les matchs?
"some string".match(/regex/g)
Réponses:
Continuez à appeler
re.exec(s)
dans une boucle pour obtenir toutes les correspondances:Essayez-le avec ce JSFiddle: https://jsfiddle.net/7yS2V/
la source
while
au lieu dedo … while
?while(m = re.exec(s))
, ce qui est une IMO anti-pattern, soit vous devez écrirem = re.exec(s); while (m) { ... m = re.exec(s); }
. Je préfère l'do ... if ... while
idiome, mais d'autres techniques fonctionneraient aussi.g
drapeau défini, sinon le pointeur interne n'est pas déplacé vers l'avant. Docs .str.match(pattern)
, sipattern
a l'indicateur globalg
, retournera toutes les correspondances sous forme de tableau.Par exemple:
la source
"All of us except @Emran:emran26, @Raju:raju13 and @Noman:noman42".match(/@(\w+):(\w+)/g)
(qui reviendront["@Emran:emran26", "@Raju:raju13", "@Noman:noman42"]
)/@\w/g
ounew RegExp("@\\w", "g")
Pour parcourir toutes les correspondances, vous pouvez utiliser la
replace
fonction:la source
C'est une solution
Ceci est basé sur la réponse de Lawnsea, mais plus courte.
Notez que l'indicateur «g» doit être défini pour déplacer le pointeur interne vers l'avant à travers les appels.
la source
renvoie toutes les correspondances sous forme de tableau.
Si, pour une raison mystérieuse, vous avez besoin des informations supplémentaires fournies
exec
, comme alternative aux réponses précédentes, vous pouvez le faire avec une fonction récursive au lieu d'une boucle comme suit (qui semble également plus cool).comme indiqué dans les commentaires précédents, il est important d'avoir
g
à la fin de la définition de regex pour faire avancer le pointeur à chaque exécution.la source
Nous commençons enfin à voir une
matchAll
fonction intégrée, voir ici pour la description et le tableau de compatibilité . Il semble que depuis mai 2020, Chrome, Edge, Firefox et Node.js (12+) soient pris en charge, mais pas IE, Safari et Opera. On dirait qu'il a été rédigé en décembre 2018, alors laissez-lui un peu de temps pour atteindre tous les navigateurs, mais j'espère qu'il y parviendra.La
matchAll
fonction intégrée est agréable car elle renvoie un itérable . Il renvoie également des groupes de capture pour chaque match! Ainsi, vous pouvez faire des choses commeIl semble également que chaque objet de correspondance utilise le même format que
match()
. Ainsi , chaque objet est un tableau de groupes de correspondance et la capture, avec trois autres propriétésindex
,input
, etgroups
. Donc ça ressemble à:Pour plus d'informations,
matchAll
il existe également une page des développeurs Google . Il existe également des polyfills / cales disponibles.la source
Basé sur la fonction d'Agus, mais je préfère ne renvoyer que les valeurs de correspondance:
la source
Les itérables sont plus agréables:
Utilisation en boucle:
Ou si vous voulez un tableau:
la source
if (m)
devrait êtreif (match)
matchAll
Si vous avez ES9
(Cela signifie que si votre système: Chrome, Node.js, Firefox, etc. prend en charge Ecmascript 2019 ou version ultérieure)
Utilisez le nouveau
yourString.matchAll( /your-regex/ )
.Si vous n'avez pas ES9
Si vous avez un système plus ancien, voici une fonction pour copier et coller facilement
exemple d'utilisation:
les sorties:
la source
Voici ma fonction pour obtenir les correspondances:
la source
Depuis ES9, il existe désormais un moyen plus simple et meilleur d'obtenir toutes les correspondances, ainsi que des informations sur les groupes de capture et leur index:
Il est actuellement pris en charge dans Chrome, Firefox, Opera. En fonction du moment où vous lisez ceci, consultez ce lien pour voir son support actuel.
la source
g
et qu'ellelastIndex
doit être réinitialisée à 0 avant l'invocation dematchAll
.Utilisez ceci...
Il renverra un tableau de toutes les correspondances ... Cela fonctionnerait très bien ... Mais rappelez-vous que cela ne prendra pas en compte les groupes ... Il ne fera que renvoyer les correspondances complètes ...
la source
Je recommanderais définitivement d'utiliser la fonction String.match () et de créer un RegEx pertinent pour cela. Mon exemple est avec une liste de chaînes, ce qui est souvent nécessaire lors de l'analyse des entrées utilisateur à la recherche de mots-clés et de phrases.
J'espère que cela t'aides!
la source
Cela n'aidera pas vraiment à résoudre votre problème plus complexe, mais je le publie quand même car c'est une solution simple pour les personnes qui ne font pas de recherche globale comme vous.
J'ai simplifié l'expression régulière dans la réponse pour être plus claire (ce n'est pas une solution à votre problème exact).
Cela semble plus verbeux qu'à cause des commentaires, voici à quoi cela ressemble sans commentaires
Notez que tous les groupes qui ne correspondent pas seront répertoriés dans le tableau en tant que
undefined
valeurs.Cette solution utilise l'opérateur de propagation ES6 pour purifier le tableau de valeurs spécifiques à l'expression régulière. Vous devrez exécuter votre code via Babel si vous souhaitez prendre en charge IE11.
la source
Voici une solution en une ligne sans boucle while .
L'ordre est conservé dans la liste résultante.
Les inconvénients potentiels sont
la source
Je suppose que s'il y avait des cas extrêmes tels que des espaces supplémentaires ou manquants, cette expression avec moins de limites pourrait également être une option:
Tester
Circuit RegEx
jex.im visualise les expressions régulières:
la source
Voici ma réponse:
la source
str
) a un format incorrect (trop de crochets). Vous ne capturez que la clé, pas la valeur. Votre code a une erreur de syntaxe et ne s'exécute pas (les dernières parenthèses). Si vous répondez à une «ancienne» question avec une réponse déjà acceptée, assurez-vous d'ajouter plus de connaissances et une meilleure réponse que celle déjà acceptée. Je ne pense pas que votre réponse fasse cela.