1
votes

quelqu'un peut-il expliquer cette expression régulière dans gsub ()?

J'essaie de comprendre une expression régulière que quelqu'un a écrite dans la fonction gsub ().

Je n'ai jamais utilisé d'expressions régulières avant de voir ce code, et j'ai essayé de comprendre comment il obtient le résultat final avec un peu de googler, mais j'ai heurté un mur pour ainsi dire.

gsub('.*(.{2}$)', '\\1',"my big fluffy cat")

Ce code renvoie les deux derniers caractères de la chaîne donnée. Dans l'exemple ci-dessus, il renverrait "at". C'est le résultat attendu, mais d'après ma brève incursion dans les expressions régulières, je ne comprends pas pourquoi ce code fait ce qu'il fait.

Ce que je comprends, c'est que le '. *' Signifie rechercher n'importe quel caractère 0 ou plus fois. Donc, il va regarder la chaîne entière et c'est ce qui sera remplacé.

La partie entre parenthèses recherche deux caractères quelconques à la fin de la chaîne. Cela aurait plus de sens pour moi si cette partie entre parenthèses était à la place du '\ 1'. Pour moi, il lirait alors regarder la chaîne entière et la remplacerait par les deux derniers caractères de cette chaîne.

Tout ce que cela fait, c'est afficher le code réel comme remplacement, par exemple ". {2} $" .

Enfin, je ne comprends pas pourquoi '\ 1' est dans la partie de remplacement de la fonction. Pour moi, cela signifie simplement remplacer la chaîne entière par une seule barre oblique inverse et le numéro un. Je dis une seule barre oblique inverse parce que je crois comprendre que la première barre oblique inverse est juste là pour faire de la deuxième barre oblique inverse un caractère non spécial.


0 commentaires

3 Réponses :


2
votes

J'espère que les exemples peuvent vous aider à mieux le comprendre:

Supposons que nous ayons une chaîne foobarabcabcdef

  • . * correspond à la chaîne entière.

  • . * abc il correspond: depuis le début correspond à tous les caractères jusqu'au dernier abc (correspondance gourmande), donc, il correspond à foobarabcabc

  • . * (...) $ correspond également à la chaîne entière, cependant, les 3 derniers caractères ont été groupés. Sans le () , la chaîne correspondante aura un groupe par défaut, group0, le () sera group1, 2, 3 .... pensez à . * (...) (...) (...) $ donc nous avons:

    group 0 : whole string
    group 1 : "abc" the first "abc"
    group 2 : "abc" the 2nd "abc"
    group 3 : "def" the last 3 chars
    

Revenons donc à votre exemple, le \\ 1 est une référence à un groupe. Ce qu'il fait est: "remplacer la chaîne entière par le texte correspondant dans le groupe1" C'est-à-dire que la partie . {2} $ est le remplacement.

Si vous ne comprenez les backslashs, vous devez référencer la syntaxe de r , je ne peux pas en dire plus. Il s'agit de s'échapper.


0 commentaires

2
votes

Une partie importante de cette expression régulière sont les crochets, c'est ce qu'on appelle le "groupe de capture".

L'expression régulière . * (. {2} $) dit - correspond à n'importe quoi et capture les 2 derniers caractères de la ligne. Le remplacement \\ 1 fait référence à ce groupe, il remplacera donc toute la correspondance par le groupe capturé, qui sont les deux derniers caractères dans ce cas.


0 commentaires

2
votes

Pour gsub , il existe deux manières d'utiliser la fonction. Le moyen le plus courant est probablement.

gsub('(.*)(.{2}$)', 'Group 1: \\1, Group 2: \\2',"my big fluffy cat")

qui renverrait

This is a TEST

Ce que cela fait est simplement de trouver les correspondances dans l'expression régulière et de les remplacer avec la chaîne de remplacement.

La deuxième façon d'utiliser gsub est la méthode que vous avez décrite. en utilisant \\ 1, \\ 2 ou \\ 3 ...

Cela regarde le premier, deuxième ou troisième groupe de capture dans votre expression régulière.

Un groupe de capture est défini par tout ce qui se trouve à l'intérieur des crochets circulaires ex: (capture_group_1) (capture_group_2) ...

Explication

Votre analyse est correcte.

Ce que je comprends, c'est que ". *" signifie rechercher un caractère 0 fois ou plus. Donc, il va regarder la chaîne entière et c'est ce qui sera remplacé.

La partie entre crochets recherche deux caractères quelconques à la fin de la chaîne

Les deux derniers caractères sont placés dans un groupe de capture et nous remplaçons simplement la chaîne entière par ce groupe de capture. Ne pas les remplacer par quoi que ce soit.

si cela peut vous aider, regardez le résultat de cette expression.

gsub("-","TEST","This is a - ")


4 commentaires

Merci, cela a beaucoup plus de sens maintenant. Bien que je ne sois pas tout à fait sûr à ce sujet: Votre code affiche: "Groupe 1: mon gros c pelucheux, Groupe 2: à" Si le groupe 1 est 'mon gros c pelucheux' alors j'aurais pensé que le résultat serait: "Groupe 1: my big moelleux c, Groupe 2: atat "car il ne remplace sûrement que la partie 'my big moelleux c' du motif. Comment se fait-il qu'il remplace tout le modèle si le groupe 1 ne regarde que la chaîne avant les deux derniers caractères?


Je suppose que le mot «remplacer» prête à confusion. Lorsque j'utilise \\ 1 , j'aime penser que c'est "extraire" cette partie du groupe de capture. Il extrait littéralement le premier groupe de capture et le deuxième groupe de capture et le place à la place de \\ 1 et \\ 2


code1: gsub ('(W [ae])', 'rn', "occidental") code2: gsub ('(W [ae]) (. {2} $)', '\\ 2', "occidental" ) Il semble que je sois plus confus à ce sujet. J'aurais pensé que ces deux lignes de code produiraient toutes les deux "rnstern" mais la deuxième ligne renvoie "Western". Le groupe 1 regarde "Nous" dans la chaîne et celui-ci sera remplacé par le groupe 2 qui est "rn". Comme cela ne se produit pas, je ne comprends pas ce qui se passe.


@Steve lorsque aucune correspondance n'est trouvée, gsub renvoie la chaîne d'origine. c'est ce qui se passe avec code2 . Cela vous donnera rn gsub ('(W [a-e]). * (. {2} $)', '\\ 2', "Western") . Code1 correspond à We en occident et le remplace par rn qui vous donne rnstern .