Ce qui est un non-capture d'un groupe? Ce n' (?:) faire?
Comment ?:
est utilisé et ce que c'est bon?
- Cette question a été ajoutée à la Débordement de Pile dans l'Expression Régulière de la FAQ, sous la rubrique "Groupes".
Vous devez vous connecter pour publier un commentaire.
Laissez-moi essayer de vous l'expliquer avec un exemple.
Considérer le texte suivant:
Maintenant, si je demande à l'expression régulière ci-dessous sur elle...
... Je voudrais obtenir le résultat suivant:
Mais je n'ai pas de soins sur le protocole -- je veux juste l'hôte et le chemin d'accès de l'URL. Donc, j'ai modifier la regex pour inclure la non-capture d'un groupe
(?:)
.Maintenant, mon résultat ressemble à ceci:
Voir? Le premier groupe n'a pas été capturé. L'analyseur utilise pour le texte, mais l'ignore plus tard, dans le résultat final.
EDIT:
Comme demandé, laissez-moi vous expliquer groupes de trop.
Bien, groupes servir à de nombreuses fins. Ils peuvent vous aider à extraire des informations exactes à partir d'un gros match (qui peut aussi être nommé), ils vous permettent de revanche d'un précédent groupe apparié, et peut être utilisé pour les substitutions. Essayons quelques exemples, allons-nous?
Ok, imaginez que vous avez une sorte de XML ou HTML (être conscient que regex peut-être pas le meilleur outil pour le travail, mais il est gentil comme un exemple). Vous souhaitez analyser les balises, donc vous pourriez faire quelque chose comme ceci (j'ai ajouté des espaces pour le rendre plus facile à comprendre):
La première regex a un groupe nommé (TAG), tandis que le second utilise un groupe commun. Les deux regexes faire la même chose: ils ont de la valeur du premier groupe (le nom de la balise) pour correspondre à la balise de fermeture. La différence est que le premier utilise le nom pour correspondre à la valeur, et le second utilise l'indice de groupe (qui commence à 1).
Essayons quelques substitutions maintenant. Considérons le texte suivant:
Maintenant, nous allons utiliser cette stupide regex sur elle:
Cette expression correspond à des mots avec au moins 3 caractères, et utilise les groupes de séparer les trois premières lettres. Le résultat est le suivant:
Donc, si nous appliquons la chaîne de substitution:
... plus de cela, nous essayons d'utiliser le premier groupe, ajouter un trait de soulignement, utilisez le troisième groupe, puis le deuxième groupe, ajouter un autre trait de soulignement, et puis le quatrième groupe. La chaîne résultante serait comme celui ci-dessous.
Vous pouvez utiliser des groupes nommés pour les substitutions, en utilisant
${name}
.Jouer avec les regexes, je recommande http://regex101.com/, qui offre une bonne quantité de détails sur la façon dont les regex fonctionne; il offre également quelques regex moteurs à choisir.
\r
et\n
dans votre regex([^/\r\n]+)(/[^\r\n]*)
correspondantstackoverflow.com
et/
. ?\r
,\n
et/ou/
. Cela signifiestackoverflow.com
correspond à cette expression. Il est suivi par/[^\r\n]*
qui correspond à n'importe quel/
qui est suivi par zéro ou plusieurs caractères qui ne sont pas\r
et/ou\n
.Vous pouvez utiliser la capture des groupes pour organiser et analyser une expression. Un non-capture d'un groupe a l'avantage premier, mais qui n'ont pas les frais généraux de la seconde. Vous pouvez toujours dire à un non-capture de groupe est facultatif, par exemple.
Dites que vous voulez de match de texte numérique, mais certains nombres peuvent être écrits comme des 1er, 2e, 3e, 4e,... Si vous voulez capturer la partie numérique, mais pas le (facultatif) suffixe, vous pouvez utiliser un non-capture d'un groupe.
Qui correspondent à des nombres de la forme 1, 2, 3... ou dans le formulaire de 1ère, 2ème, 3ème,... mais il va capturer uniquement la partie numérique.
?:
est utilisé lorsque vous souhaitez une expression, mais vous ne voulez pas enregistrer en tant que appariés/capturé partie de la chaîne.Un exemple serait quelque chose pour correspondre à une adresse IP:
Remarque que je n'aime pas à propos de l'enregistrement les 3 premiers octets, mais le
(?:...)
groupement me permet de raccourcir la regex sans encourir les frais généraux de la capture et du stockage d'un match.Il fait le groupe de non-capture, ce qui signifie que la sous-chaîne correspondant au groupe ne sera pas inclus dans la liste de capture. Un exemple en ruby pour illustrer la différence:
HISTORIQUE de la MOTIVATION: L'existence de non-capture de groupes peut être expliqué par l'utilisation de parenthèses. Considérons les expressions (a|b)c et a|bc, en raison de la priorité de concaténation sur |, ces expressions représentent deux langues différentes ({ac, bc} et {a, bc}, respectivement). Cependant, les parenthèses sont utilisées aussi comme un groupe correspondant (comme expliqué par les autres réponses...).
Quand vous voulez avoir des parenthèses, mais pas de capture de la sous-expression que vous utilisez NON-CAPTURE de GROUPES. Dans l'exemple, (?:a|b)c
Groupes capture vous pouvez utiliser plus tard dans la regex pour correspondre à OU vous pouvez les utiliser dans le remplacement de la partie de l'expression régulière. Faire un non-capture groupe, il suffit de dispense de ce groupe d'être utilisé pour une de ces raisons.
Non-capture de groupes sont très bien si vous êtes en essayant de capturer beaucoup de choses différentes et il y a quelques groupes que vous ne voulez pas capturer.
C'est à peu près la raison pour laquelle ils existent. Pendant que vous apprenez sur les groupes, en apprendre davantage sur Groupes Atomiques, ils font beaucoup! Il est également lookaround groupes, mais ils sont un peu plus complexes et ne sont pas utilisés.
Exemple d'utilisation de la suite dans les regex (référence arrière):
<([A-Z][A-Z0-9]*)\b[^>]*>.*?</\1>
[ Trouve une balise xml (sans ns de soutien) ]([A-Z][A-Z0-9]*)
est une capture d'un groupe (dans ce cas c'est le tagname)Plus tard dans la regex est
\1
ce qui signifie qu'il ne fait correspondre le même texte qui était dans le premier groupe (les([A-Z][A-Z0-9]*)
groupe) (dans ce cas, il est correspondant à la balise de fin).Laissez-moi essayer cela avec un exemple :-
Regex Code :-
(?:animal)(?:=)(\w+)(,)\1\2
Chaîne De Recherche :-
Ligne 1 -
animal=cat,dog,cat,tiger,dog
Ligne 2 -
animal=cat,cat,dog,dog,tiger
Ligne 3 -
animal=dog,dog,cat,cat,tiger
(?:animal)
--> Non saisis Groupe 1(?:=)
--> Non saisis Groupe 2(\w+)
--> Capturé Groupe 1(,)
--> Groupe Capturé 2\1
--> résultat de la capture de groupe 1 je.e Dans la Ligne 1 est le chat,Dans la Ligne 2 est le chat,Dans la Ligne 3 est chien.\2
-->résultat de la capture de groupe 2 je.e par des virgules(,)Donc dans ce code par exemple: \1 et \2, nous le rappelons, ou de répéter le résultat de la capture de groupe 1 et 2 respectivement, plus tard dans le code.
Selon l'ordre de code (?:animal) doit être groupe 1 et (?:=) devrait être le groupe 2 et continue..
mais, en leur donnant l' ?: nous faisons le match-groupe non pris en compte(qui ne compte pas éteint dans le groupe correspondant, de sorte que le groupement de nombre commence à partir du premier groupe capturé et non pas le non capturé), de sorte que la répétition du résultat du match-groupe de (?:animal) ne peut pas être appelé plus tard dans le code.
De l'espoir c'est ce qui explique la non-utilisation de la capture de groupe.
entrez la description de l'image ici
Complexes dans les expressions régulières, vous pouvez avoir le cas où vous souhaitez utiliser un grand nombre de groupes dont certains sont là pour la répétition de correspondance et certains sont là pour fournir des références. Par défaut, le texte correspondant à chaque groupe est chargé dans la référence arrière du tableau. Où nous avons beaucoup de groupes et ont seulement besoin d'être en mesure de faire référence à certains d'entre eux à partir de la référence arrière tableau, nous pouvons remplacer ce comportement par défaut de dire à l'expression régulière que certains groupes ne sont là que pour la répétition de la manipulation et de la nécessité de ne pas être capturées et stockées dans la référence arrière du tableau.
Eh bien, je suis un développeur JavaScript et va tenter d'expliquer son importance concernant JavaScript.
Envisager un scénario où vous voulez faire correspondre
cat is animal
lorsque vous souhaitez correspondre à chat et les animaux, et les deux devraient avoir un
is
entre eux.tl;dr non-capture de groupes, comme son nom l'indique, sont les parties de l'expression régulière que vous ne voulez pas être inclus dans le match et
?:
est un moyen de définir un groupe comme étant non-capture.Disons que vous avez une adresse e-mail
[email protected]
. La regex suivante va créer deux groupes, l'id de la partie et @example.com partie.(\p{Alpha}*[a-z])(@example.com)
. Par souci de simplicité, nous l'extraction de l'ensemble du nom de domaine, y compris la@
caractère.Disons-le maintenant, vous avez seulement besoin de l'id de la partie de l'adresse. Ce que vous voulez faire est de saisir le premier groupe, le résultat du match, entouré par
()
dans la regex et la façon de le faire est d'utiliser la non-capture d'un groupe de syntaxe, c'est à dire?:
. Donc la regex(\p{Alpha}*[a-z])(?:@example.com)
sera de retour juste l'id de la partie de l'e-mail.Une chose intéressante que j'ai trouvé est le fait que vous pouvez avoir une capture d'un groupe à l'intérieur d'un non-capture d'un groupe. Regardez ci-dessous regex pour la mise en correspondance des url web:
Url d'entrée de la chaîne:
Le premier groupe dans ma regex
(?:([A-Za-z]+):)
est un non-capture d'un groupe qui correspond au schéma de protocole et du côlon:
caractère c'est à direhttp:
mais quand j'ai été l'exécution de code ci-dessous, j'ai été voir le 1er indice du tableau retourné était contenant la chaîne de caractèreshttp
quand je pensais quehttp
et du côlon:
les deux ne seront pas signalés car ils sont à l'intérieur d'un non-capture d'un groupe.J'ai pensé que, si le premier groupe
(?:([A-Za-z]+):)
est un non-capture d'un groupe, alors pourquoi il est de retourhttp
chaîne dans le tableau de sortie.Donc, si vous remarquez qu'il y a un groupe imbriqué
([A-Za-z]+)
à l'intérieur de la non-capture d'un groupe. Que groupe imbriqué([A-Za-z]+)
est une capture d'un groupe (ne pas avoir de?:
au début) dans lui-même à l'intérieur d'un non-capture d'un groupe(?:([A-Za-z]+):)
. C'est pourquoi le textehttp
toujours est capturé mais le côlon:
personnage qui est à l'intérieur de la non-capture d'un groupe, mais à l'extérieur de la capture d'un groupe à ne pas avoir rapporté dans le tableau de sortie.Je ne peux pas commenter sur les réponses les plus fréquentes à dire ceci: je voudrais ajouter explicitement un point qui n'est qu'implicite dans le top des réponses:
La non-capture d'un groupe
(?...)
ne pas supprimer tous les caractères à partir de l'original de match, il ne réorganise les regex visuellement pour le programmeur.
Pour accéder à une partie spécifique de la regex sans défini étrangères caractères que vous aurait toujours besoin d'utiliser
.group(<index>)
Je pense que je voudrais vous donner la réponse,
N'utilisez pas de capture de variables sans vérifier que le match réussi.
La capture de variables $1, etc, ne sont valables que si le match a réussi, et ils ne sont pas effacés, soit.
Dans l'exemple ci-dessus, À éviter la capture bronto dans $1, (?:) est utilisée.
Si le profil correspond , puis $1 est capturée comme prochaine regroupés modèle.
Donc, la sortie sera comme ci-dessous:
Il est Utile si vous ne voulez pas les matchs pour être sauvé .
Ouvrir votre Google Chrome devTools, puis sur l'onglet Console: et tapez ceci:
L'exécuter et vous verrez:
La
JavaScript
RegExp moteur de la capture de trois groupes, les éléments avec les indices 1, 2 et 3. Maintenant, l'utilisation non-capture de marque pour voir le résultat.Le résultat est:
C'est évident que ce qui est non capture d'un groupe.
Extrêmement simple, Nous pouvons comprendre avec une simple date supposons, par exemple, si la date est mentionné que le 1er janvier 2019 ou 2 Mai 2019 ou à une autre date, et nous voulons simplement convertir jj/mm/aaaa format que nous n'aurions pas besoin de le mois du nom de laquelle est, en janvier ou en février de cette question, de sorte afin de capturer la partie numérique, mais pas le (facultatif) suffixe, vous pouvez utiliser un non-capture d'un groupe.
donc l'expression régulière serait,
Son aussi simple que cela.