Comment rendre mon match non gourmand dans vim?

481

J'ai un gros fichier HTML qui a beaucoup de balisage qui ressemble à ceci:

<p class="MsoNormal" style="margin: 0in 0in 0pt;">
  <span style="font-size: small; font-family: Times New Roman;">stuff here</span>
</p>

J'essaie de faire une recherche et un remplacement Vim pour se débarrasser de tout class=""et style=""j'ai du mal à rendre le match non hideux.

Ma première tentative a été celle-ci

%s/style=".*?"//g

mais Vim ne semble pas aimer le ?. Malheureusement, la suppression du ?rend le match trop gourmand.

Comment puis-je rendre mon match non hideux?

Mark Biek
la source
Je pense que la réponse de Paul est bonne. Juste pour dire que "?" ne signifie pas facultatif dans vim (si c'est ce que vous voulez réaliser en utilisant "?")
LB40
15
@LB, en plusieurs langues,. *? signifie correspondre à n'importe quel caractère mais ne pas être gourmand. C'est ce qu'il essaie de réaliser.
Randy Morris
Connexes: Comment rendre les allumeurs regex non gourmands? sur Vim SE.
Big McLargeHuge

Réponses:

735

Au lieu d' .*utilisation .\{-}.

%s/style=".\{-}"//g

Regarde aussi :help non-greedy

Randy Morris
la source
38
Pas très intuitif, est-ce quelque chose que seul Vim fait?
Ehtesh Choudhury
95
Tout a son propre langage d'expression régulière ... c'est l'un des plus gros problèmes avec l'expression régulière.
Patrick Farrell
35
Beaucoup de ces outils ont mûri à peu près au même moment et développé indépendamment leur propre dialecte d'un langage d'expression régulière. Beaucoup de ces outils essayaient également de résoudre différents problèmes, il est donc logique que la syntaxe puisse être -peut-être énormément différente entre ces implémentations. Nous devons accepter que c'est exactement ainsi que fonctionne le monde réel même si cela rend parfois notre vie plus difficile en tant que développeurs. Heureusement, de nombreux outils fournissent au moins une implémentation de regex compatible Perl de nos jours. Malheureusement, Vim n'en fait pas partie.
Randy Morris
15
Si quelqu'un comme moi par défaut recherche \v(drapeau très magique), vous voudrez l'utiliser .{-}.
jgillman
48
@Shurane @Ziggy Mnemonic: contrôle le nombre de répétitions comme les {1,3}accolades. Le signe moins -signifie: répéter le moins possible (petit == moins);)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
58

La recherche non gourmande dans vim se fait en utilisant l'opérateur {-}. Comme ça:

%s/style=".\{-}"//g

essayez juste:

:help non-greedy
Vilhelm Grey
la source
48

Quel est le problème avec

%s/style="[^"]*"//g
Paul Tomblin
la source
7
Bien que, pour mon propre bénéfice, j'aimerais quand même mieux comprendre la chose non honteuse.
Mark Biek
17

Si vous êtes plus à l'aise avec la syntaxe regex PCRE, qui

  1. prend en charge l'opérateur non gourmand?, comme vous l'avez demandé dans OP; et
  2. ne nécessite pas de regroupement de backwhacking et d'opérateurs de cardinalité (une exigence de syntaxe Vim totalement contre-intuitive puisque vous ne faites pas correspondre des caractères littéraux mais spécifiez des opérateurs); et
  3. vous avez [g] vim compilé avec la fonction perl, testez en utilisant

    : ver et inspecter les fonctionnalités; si + perl est là, vous êtes prêt à partir)

essayez de rechercher / remplacer en utilisant

:perldo s///

Exemple. Échangez les attributs src et alt dans la balise img:

<p class="logo"><a href="/"><img src="/caminoglobal_en/includes/themes/camino/images/header_logo.png" alt=""></a></p>

:perldo s/(src=".*?")\s+(alt=".*?")/$2 $1/

<p class="logo"><a href="/"><img alt="" src="/caminoglobal_en/includes/themes/camino/images/header_logo.png"></a></p>
FrDarryl
la source
1
perldofonctionne très bien, mais ne met malheureusement pas en évidence le test sélectionné lors de la frappe de l'expression rationnelle.
mljrg
12

J'ai trouvé qu'une bonne solution à ce type de question est:

:%! sed ...

(ou Perl si vous préférez). IOW, plutôt que d'apprendre les particularités des expressions rationnelles de vim, utilisez un outil que vous connaissez déjà. Utiliser perl ferait le? travail de modificateur pour dégoûter le match.

William Pursell
la source
2
bon point, mais être capable de /patternvérifier que vous correspondez correctement au motif avant de l'appliquer et d'utiliser le cmodificateur dans votre expression régulière vim est également agréable :)
João Portela
c'est correct. toutes les solutions ici ne sont pas proches de non gourmandes! si vous devez faire correspondre [0-9] \ {7} dans une ligne avec beaucoup de texte et plusieurs occurrences de ce modèle, aucune solution ici ne fera l'affaire. Les solutions ici ne fonctionnent que pour des choses simples (ce qui, pour être juste, est ce qui a été demandé). mais si vous faites un peu plus que chercher jusqu'à la prochaine citation, vim ne vous aidera pas.
gcb
4

Avec \v(comme suggéré dans plusieurs commentaires)

:%s/\v(style|class)\=".{-}"//g
JJoao
la source
2

Le plugin eregex.vim gère les opérateurs non gourmands de style Perl *?et+?

bain
la source
@xsilenT github.com/othree/eregex.vim : "Il est recommandé d'installer le script à l'aide de Vundle ou d'un pathogène."
eXe
désolé pour cela, je ne sais pas comment utiliser Vundle ou un pathogène.
xsilen T
-4

G'day,

Le traitement regexp de Vim n'est pas trop brillant. J'ai trouvé que la syntaxe regexp pour sed correspond à peu près aux capacités de vim.

Je règle habituellement la mise en évidence de la recherche sur (: set hlsearch), puis je joue avec l'expression rationnelle après avoir entré une barre oblique pour passer en mode de recherche.

Edit: Mark, cette astuce pour minimiser les correspondances gourmandes est également couverte dans l'excellent livre "Sed & Awk" de Dale Dougherty ( lien Amazon aseptisé ).

Le chapitre trois "Comprendre la syntaxe des expressions régulières" est une excellente introduction aux capacités d'expression rationnelle plus primitives impliquées avec sed et awk. Seulement une courte lecture et fortement recommandé.

HTH

à votre santé,

Rob Wells
la source
7
Le traitement des regex de Vim est en fait assez agréable. Il peut faire des choses que sed ne peut pas faire, comme une correspondance sur des numéros de ligne / colonne ou une correspondance basée sur une classification par langue des caractères en tant que mots clés ou identificateurs ou espaces blancs. Il a également des assertions de largeur nulle et la possibilité de mettre des expressions dans le côté droit d'un remplacement. Si vous l'utilisez, \vcela aide beaucoup à nettoyer la syntaxe.
Brian Carper
1
@Brian, cheers. Je vais faire un regex d'aide et voir ce que j'ai manqué.
Rob Wells
@RobWells, Sed & Awk , qui est en effet un très bon livre, ne dépense pas explicitement de mots sur des quantificateurs gourmands / paresseux. Pour preuve, il n'y a absolument aucune occurrence des mots cupidité ou gourmand dans le livre, et il n'y a qu'une seule occurrence, mais sans rapport, du mot paresseux .
Enrico Maria De Angelis
@EnricoMariaDeAngelis, mais l'exemple ne fait pas explicitement référence au terme. Il s'agit de savoir comment personnaliser votre expression régulière pour utiliser l'opérateur "not" pour obtenir des correspondances non gourmandes. Le terme gourmand et paresseux est arrivé avec le moteur NFA de Perl lorsqu'ils ont introduit des opérateurs pour modifier spécifiquement le comportement de match gourmand.
Rob Wells