Question

Je dois obtenir tout le texte entre <Annotation> et </Annotation>, où un mot MATCH se produit. Comment puis-je faire dans VIM?

<Annotation about="MATCH UNTIL </Annotation>   " timestamp="0x000463e92263dd4a" href="     5raS5maS90ZWh0YXZha29rb2VsbWEvbGFza2FyaS8QyrqPk5L9mAI">                                                                        
  <Label name="las" />
  <Label name="_cse_6sbbohxmd_c" />
  <AdditionalData attribute="original_url" value="MATCH UNTIL </Annotation>       " />
</Annotation>
<Annotation about="NO MATCH" href="     Cjl3aWtpLmhlbHNpbmtpLmZpL2Rpc3BsYXkvbWF0aHN0YXRLdXJzc2l0L0thaWtraStrdXJzc2l0LyoQh_HGoJH9mAI">
  <Label name="_cse_6sbbohxmd_c" />
  <Label name="courses" />
  <Label name="kurssit" />
  <AdditionalData attribute="original_url" value="NO MATCH" />
</Annotation>
<Annotation about="MATCH UNTIL </ANNOTATION>     " score="1" timestamp="0x000463e90f8eed5c" href="CiZtYXRoc3RhdC5oZWx     zaW5raS5maS90ZWh0YXZha29rb2VsbWEvKhDc2rv8kP2YAg">
  <Label name="_cse_6sbbohxmd_c" />
  <Label name="exercises_without_solutions" />
  <Label name="tehtäväkokoelma" />
  <AdditionalData attribute="original_url" value="MATCH UNTIL </ANNOTATION>" />
</Annotation>
Était-ce utile?

La solution

Est-il doivent se faire dans vim? Pourriez-vous tricher, et ouvrir une deuxième fenêtre dans laquelle vous redirigez quelque chose en plus / moins que vous dit ce numéro de ligne pour aller à l'intérieur vim?

- modifier -

Je ne l'ai jamais fait un match / recherche multi-ligne vi [m]. Cependant, pour tricher dans une autre fenêtre:

perl -n -e 'if ( /<tag/ .. /<\/tag/)' -e '{ print "$.:$_"; }' file.xml | less

affiche les éléments / blocs pour « tag » (ou tout autre nom correspondant à plus), les numéros de ligne, en moins, et vous pouvez ensuite rechercher l'autre texte dans chaque bloc.

Assez proche?

- modifier -

dans les "moins", tapez

/MATCH

pour rechercher des occurrences de MATCH. Sur la marge de gauche sera le numéro de ligne où cette instance (dans les éléments ciblés / balises) est.

à l'intérieur vi [m], le type

:n

où "n" est le numéro de ligne souhaité.

Bien sûr, si ce que tu voulais vraiment faire était une sorte de recherche / Yank / remplacer, il est plus compliqué. À ce moment-là, awk / perl / rubis (ou quelque chose de similaire qui répond à vos goûts ... ou xsl?) Est vraiment l'outil que vous devez utiliser pour la transformation.

Autres conseils

Tout d'abord, un avertissement: Toute tentative de couper et XML dés avec des expressions régulières est fragile; un véritable analyseur XML ferait mieux.

Le schéma:

\(<Annotation\(\s*\w\+="[^"]\{-}"\s\{-}\)*>\)\@<=\(\(<\/Annotation\)\@!\_.\)\{-}"MATCH\_.\{-}\(<\/Annotation>\)\@=

Brisons le bas ...

Groupe 1 est <Annotation\(\s*\w\+="[^"]\{-}"\s\{-}\)*>. Il correspond à la balise de début de l'élément d'attribut. Le groupe 2, qui est intégré dans le Groupe 1, correspond à un attribut et peut être répété 0 fois ou plus.

Groupe 2 est \s*\w\+="[^"]\{-}"\s\{-}. La plupart de ces pièces sont couramment utilisés; le plus insolite est \{-}, ce qui signifie que la répétition non gourmand (*? dans les expressions régulières Perl compatibles). Le match des espaces non-gourmand à la fin est importante pour la performance; sans elle, Vim essaiera tous les moyens possibles de diviser l'espace entre les attributs entre les \s* à la fin du groupe 2 et le \s* au début de la prochaine occurrence du groupe 2.

Groupe 1 est suivi par \@<=. Ceci est un facteur positif zéro largeur regarder en arrière. Il empêche la balise de début d'être inclus dans le texte correspondant (par exemple, pour s ///).

Groupe 3 est \(<\/Annotation\)\@!\_.. Il comprend le groupe 4, qui correspond au début de l'attribut balise de fin. Le \@! est une anticipation négative zéro largeur et \_. correspond à tout caractère (y compris les nouvelles lignes). Ensemble, ces groupes correspond à tout caractère sauf si l'attribut balise de fin commence. Groupe 3 est suivi d'un marqueur de répétition non avide \{-} afin qu'il corresponde le plus petit bloc de texte avant MATCH. Si vous deviez utiliser \_. au lieu du groupe 3, le texte correspondant pourrait inclure la balise de fin d'un élément d'annotation qui a fait pas comprennent MATCH JUSQU dans l'élément suivant Annotation avec MATCH. (Essayez.)

Le bit suivant est simple: Trouver MATCH et un nombre minimal d'autres caractères avant la balise de fin

.

Groupe 5 est facile: Il est la balise de fin. \@= est un regard vert positif zéro largeur, qui est inclus ici pour la même raison que le \@<= pour la balise de début. Nous devons répéter <\/Attribute plutôt que d'utiliser \4 parce que les groupes modificateurs zéro largeur ne sont pas pris.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top