Pour autant que je sache, il n'existe pas de groupes de capture nommés en JavaScript. Quelle est la méthode alternative pour obtenir des fonctionnalités similaires?
javascript
regex
mmierins
la source
la source
Réponses:
ECMAScript 2018 introduit des groupes de capture nommés dans les expressions rationnelles JavaScript.
Exemple:
Si vous devez prendre en charge des navigateurs plus anciens, vous pouvez tout faire avec des groupes de capture normaux (numérotés) que vous pouvez faire avec des groupes de capture nommés, il vous suffit de garder une trace des numéros - ce qui peut être lourd si l'ordre de capture du groupe dans votre changements d'expression régulière.
Les groupes de capture nommés ne présentent que deux avantages "structurels":
Dans certaines versions de regex (.NET et JGSoft, pour autant que je sache), vous pouvez utiliser le même nom pour différents groupes dans votre regex ( voir ici pour un exemple où cela est important ). Mais la plupart des versions regex ne prennent pas en charge cette fonctionnalité de toute façon.
Si vous devez faire référence à des groupes de capture numérotés dans une situation où ils sont entourés de chiffres, vous pouvez obtenir un problème. Disons que vous voulez ajouter un zéro à un chiffre et que vous souhaitez donc le remplacer
(\d)
par$10
. En JavaScript, cela fonctionnera (tant que vous avez moins de 10 groupes de capture dans votre expression régulière), mais Perl pensera que vous recherchez un numéro de référence10
au lieu d'un nombre1
, suivi d'un0
. En Perl, vous pouvez utiliser${1}0
dans ce cas.En dehors de cela, les groupes de capture nommés ne sont que du «sucre syntaxique». Il est utile d'utiliser des groupes de capture uniquement lorsque vous en avez vraiment besoin et d'utiliser des groupes non capturés.
(?:...)
dans toutes les autres circonstances.Le plus gros problème (à mon avis) avec JavaScript est qu'il ne prend pas en charge les expressions rationnelles verbeuses, ce qui faciliterait la création d'expressions régulières complexes et lisibles.
La bibliothèque XRegExp de Steve Levithan résout ces problèmes.
la source
Vous pouvez utiliser XRegExp , une implémentation augmentée, extensible et multi-navigateur d'expressions régulières, y compris la prise en charge de syntaxe, indicateurs et méthodes supplémentaires:
s
pour faire correspondre les points à tous les caractères (aka mode dotall ou singleline), etx
, pour l'espacement libre et les commentaires (aka mode étendu).la source
Autre solution possible: créer un objet contenant les noms de groupe et les index.
Ensuite, utilisez les clés d'objet pour référencer les groupes:
Cela améliore la lisibilité / qualité du code en utilisant les résultats de l'expression régulière, mais pas la lisibilité de l'expression régulière elle-même.
la source
Dans ES6, vous pouvez utiliser la déstructuration de tableau pour intercepter vos groupes:
Remarquer:
let
ignore la première valeur du tableau résultant, qui correspond à la chaîne entière correspondante|| []
after.exec()
empêchera une erreur de déstructuration quand il n'y a pas de correspondance (car.exec()
reviendranull
)la source
String.prototype.match
renvoie un tableau avec: toute la chaîne correspondante à la position 0, puis tous les groupes après cela. La première virgule dit "sauter l'élément en position 0"RegExp.prototype.exec
plusString.prototype.match
d'endroits où la chaîne peut êtrenull
ouundefined
.Mise à jour: il est enfin devenu JavaScript (ECMAScript 2018)!
Les groupes de capture nommés pourraient très bientôt devenir JavaScript.
La proposition en est déjà à l'étape 3.
Un groupe de capture peut recevoir un nom entre crochets angulaires à l'aide de la
(?<name>...)
syntaxe, pour tout nom d'identifiant. L'expression régulière d'une date peut alors s'écrire/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/u
. Chaque nom doit être unique et suivre la grammaire d'ECMAScript IdentifierName .Les groupes nommés sont accessibles à partir des propriétés d'une propriété de groupes du résultat de l'expression régulière. Des références numérotées aux groupes sont également créées, tout comme pour les groupes non nommés. Par exemple:
la source
let {year, month, day} = ((result) => ((result) ? result.groups : {}))(re.exec('2015-01-02'));
Nommer les groupes capturés fournit une chose: moins de confusion avec les expressions régulières complexes.
Cela dépend vraiment de votre cas d'utilisation, mais peut-être qu'une jolie impression de votre expression régulière pourrait vous aider.
Ou vous pouvez essayer de définir des constantes pour faire référence à vos groupes capturés.
Les commentaires peuvent également aider à montrer aux autres qui ont lu votre code ce que vous avez fait.
Pour le reste, je dois être d'accord avec la réponse de Tims.
la source
Il existe une bibliothèque node.js appelée named-regexp que vous pouvez utiliser dans vos projets node.js (dans le navigateur en empaquetant la bibliothèque avec browserify ou d'autres scripts d'empaquetage). Cependant, la bibliothèque ne peut pas être utilisée avec des expressions régulières qui contiennent des groupes de capture non nommés.
Si vous comptez les accolades de capture d'ouverture dans votre expression régulière, vous pouvez créer un mappage entre les groupes de capture nommés et les groupes de capture numérotés dans votre expression régulière et pouvez mélanger et assortir librement. Il vous suffit de supprimer les noms de groupe avant d'utiliser l'expression régulière. J'ai écrit trois fonctions qui le démontrent. Voir cet essentiel: https://gist.github.com/gbirke/2cc2370135b665eee3ef
la source
Comme l'a dit Tim Pietzcker , ECMAScript 2018 introduit des groupes de capture nommés dans les expressions rationnelles JavaScript. Mais ce que je n'ai pas trouvé dans les réponses ci-dessus, c'est comment utiliser le groupe capturé nommé dans l'expression régulière elle-même.
vous pouvez utiliser le groupe capturé nommé avec cette syntaxe:
\k<name>
. par exempleet comme Forivin l'a dit, vous pouvez utiliser le groupe capturé dans le résultat de l'objet comme suit:
la source
Bien que vous ne puissiez pas le faire avec JavaScript vanilla, vous pouvez peut-être utiliser une
Array.prototype
fonction telle queArray.prototype.reduce
transformer les correspondances indexées en correspondances nommées en utilisant de la magie .De toute évidence, la solution suivante devra que les correspondances se produisent dans l'ordre:
la source
var assocArray = Regex("hello alex, I am dennis", "hello ({hisName}.+), I am ({yourName}.+)");
RegExp
objet en ajoutant une fonction à son prototype.Vous n'avez pas ECMAScript 2018?
Mon objectif était de faire en sorte que cela fonctionne le plus possible avec ce à quoi nous sommes habitués avec les groupes nommés. Alors que dans ECMAScript 2018, vous pouvez placer
?<groupname>
à l'intérieur du groupe pour indiquer un groupe nommé, dans ma solution pour les anciens javascript, vous pouvez placer(?!=<groupname>)
à l'intérieur du groupe pour faire la même chose. C'est donc un ensemble supplémentaire de parenthèses et un extra!=
. Assez proche!J'ai tout enveloppé dans une fonction de prototype de chaîne
Caractéristiques
Instructions
(?!={groupname})
à l'intérieur de chaque groupe que vous souhaitez nommer()
en les mettant?:
au début de ce groupe. Ceux-ci ne seront pas nommés.arrays.js
usage
résultat de o
la source