Forum Linux.général Vim: comment utiliser un pattern après son matching?

Posté par  .
Étiquettes :
3
7
fév.
2012

Bonjour,
j'ai eu besoin des fonctionnalités de scripting de Vim aujourd'hui, et je n'ai pas su comment réutiliser un pattern lorsqu'il était matché.
Voilà le type de fonction que j'avais défini (sachant que le contexte justifiait ce type de méthode) :

:function Remplacer(line)
:if a:line =~ "^#\(.*\)"
:let @a=\1 "<----------- ici j'aurais voulu "capturer" le contenu matché par les \( \)
:normal O"ap "<------- ici je réutilise ce contenu depuis (par exemple)le registre "a
:endif
:endfunction

Malheureusement ça n'est pas si simple, et le code ci-dessus est invalide.

Est-ce que quelqu'un a rencontré un problème similaire ? Ou aurait une idée de la solution ?

  • # Une solution

    Posté par  (site web personnel) . Évalué à 3.

    fun! Rep(line)
      let result = matchstr(a:line, "#\\(.*\\)$")
      if result != ""
        let @a = result
        normal O
        normal O"ap"ap
      endif
    endfun
    
    
    • [^] # Re: Une solution

      Posté par  . Évalué à 0.

      Merci beaucoup ! \o/

      ありがとう!!
      (ウィキペディアのアルメオです。覚えてますかw)

    • [^] # Re: Une solution

      Posté par  . Évalué à 0.

      En fait j'ai de nouveau une question.
      La fonction matchstr() ne semble pas supporter complètement la greedy search "*".
      Si je tape

      :echo matchstr("zgzegeeeeefefe","e*")
      
      

      je n'obtiens rien.
      Est-ce normal ? Y a-t-il des options à rajouter ?

      • [^] # Re: Une solution

        Posté par  (site web personnel) . Évalué à 3.

        La chaîne de caractères vide matche bien "e" de manière gloutonne, donc c'est normal.
        Si tu veux au moins un "e", c'est "ee
        " qu'il te faut.
        Et tu auras toujours la première réponse, pas la plus grande… Donc "eeAeeeeee" te rendra "ee".

        • [^] # Re: Une solution

          Posté par  . Évalué à 0.

          Ah oui, en effet, pour avoir par exemple la plus grande suite de "e" dans "jvjjeeeeeefd" je dois taper :

          :echo matchstr("jvjjeeeeeefd","e*[^e]")
          
          

          Par contre, dans le cas où, comme dans le post principal, j'ai besoin de préciser l'entourage de mon motif (par exemple je veux préciser qu'avant il y a un "j" et que après il y a un "f"), en ne renvoyant toutefois le motif central, j'ai l'impression que ni les "\( \)" ni les "\zs \ze" ne fonctionnent.
          Est-ce normal ? Est-ce que j'ai loupé quelque chose ?

          Par exemple j'aurais voulu pouvoir faire :

          :echo matchstr("jvjjeeeeeefd","j\zse*\zef")
          
          
          • [^] # Re: Une solution

            Posté par  . Évalué à 0. Dernière modification le 07 février 2012 à 17:06.

            Je me réponds moi-même : j'ai trouvé ! \o/
            Il faut faire attendtion à deux trucs :
            1/ bien penser à redoubler les barres obliques inversées (comme tu l'as indiqué Axioplase), car la chaîne est interprétée une première fois avant d'être passée à la fonction (matchstr)
            2/ bien penser à utiliser \zs et \ze à la place de \( et \), car les premiers signalent que le pattern matché sera "exporté", alors que les seconds ne servent que lorsque le pattern matché est réutilisé à l'intérieur-même de l'expression (par exemple dans l'expression s/Je m'appelle \([^.]*\)\./Vous vous appelez \1\./)

            En conclusion voici le type de commande qui marche bien :

            :echo matchstr("ueeeeeemlmlmpe","u\\zse*\\ze[^e]")
            
            

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.