vim regex pour remplacer plusieurs espaces consécutifs avec un seul espace
Je travaille souvent avec des fichiers texte qui ont une quantité variable d'espaces comme des séparateurs de mots (traitements de texte comme Word, de distribuer équitablement les espaces montant dû aux différentes tailles de lettres dans certaines polices de caractères et ils ont mis cette fâcheuse quantité variable d'espaces, même lors de l'enregistrement en tant que texte brut).
Je voudrais automatiser le processus de remplacement de ces séquences d'espaces qui ont de longueur variable avec des espaces simples. Je soupçonne une regex pourrait le faire, mais il y a aussi des espaces au début des paragraphes (généralement quatre d'entre eux, mais pas toujours), à laquelle je voudrais laisser inchangé, donc, fondamentalement, ma regex convient également de ne pas toucher la pointe d'espaces et de ce qui ajoute à la complexité.
J'utilise vim, donc une regex dans le vim regex dialecte serait très utile pour moi, si c'est faisable.
Au courant de mes progrès ressemble à ceci:
:%s/ \+/ /g
mais il ne fonctionne pas correctement.
J'envisage aussi d'écrire un script vim qui a pu analyser les lignes de texte un par un, chaque ligne de char par char et ignorer les espaces après le premier, mais j'ai le sentiment que ce serait exagéré.
- Bon pour un reformatage verticalement alignées code 🙂
Vous devez vous connecter pour publier un commentaire.
Dans l'intérêt de pragmatisme, j'ai tendance à tout faire il comme un processus en trois étapes:
Je ne doute pas qu'il peut y avoir une meilleure façon (peut-être à l'aide de macros ou même un pur regex façon), mais j'ai l'habitude de trouver ce qui fonctionne quand je suis pressée. Bien sûr, si vous avez des lignes de départ avec
XYZZYPARA
, vous pouvez ajuster la chaîne 🙂C'est assez bon à tourner:
dans:
s
est la commande de substitution lui-même. Si vous lisez la dernière partie de ma réponse, il explique lag
simplement pour sélectionner les lignes, puis exécute une commande arbitraire sur chacun d'eux, de ce quis
est une possibilité. Par exemple:g/^$/d
va exécuter led
de commande (supprimer la ligne) sur l'ensemble des lignes vides. Vous pouvez avoir toutes sortes de plaisir comme avec:g/^/m0
🙂ce sera de remplacer les 2 ou plusieurs espaces
ou vous pouvez ajouter un espace avant le
\+
à votre versionCela fera l'affaire:
De nombreuses substitutions peuvent être fait dans Vim plus facile qu'avec d'autres regex dialectes à l'aide de la
\zs
et\ze
méta-séquences. Ce qu'ils font est d'exclure une partie de la correspondance du résultat final, soit la partie avant de la séquence (\zs
, “s” pour “commencez ici”) ou de la partie après (\ze
, “e” pour “fin ici”). Dans ce cas, le modèle doit correspondre à un caractère non espace première ([^ ]
), mais les suivantes\zs
dit que le score final (qui est ce qui va être remplacé) commence après ce caractère.Car il n'existe aucun moyen d'avoir un caractère non espace en face de la ligne de pointe espaces, il sera pas être compensée par le modèle, de sorte que la substitution ne le remplacera pas. Simple.
%s!\S\@<= \+! !g
. Le\@<=
est un très beau canard que j'aime l'utiliser. Voir aussi:help /\@<=
zs
plus de taper@<=
... de la même façon (dans une moindre mesure) que j'aime Vim mieux que E(scape)M(eta)A(lt)C(contrôlez)S(hift). 🙂 Otoh, que, son sens de flair est toujours d'une valeur de sacrifice, alors n'hésitez pas.Il y a beaucoup de bonnes réponses ici (surtout Aristote:
\zs
et\ze
sont bien la peine d'apprendre). Juste pour être complet, vous pouvez aussi le faire avec un négatif look-derrière l'affirmation:Ce dit "trouver 2 ou plusieurs espaces (
' \{2,}'
) qui ne sont PAS précédés par "le début de la ligne suivie par zéro, un ou plusieurs espaces". Si vous préférez afin de réduire le nombre de barres obliques inverses, vous pouvez également le faire:mais il vous fait gagner deux personnages! Vous pouvez également utiliser
' +'
au lieu de' {2,}'
si vous n'avez pas l'esprit d'en faire une charge de la redondance des changements (c'est à dire la modification d'un espace unique à un seul espace).Vous pouvez également utiliser la négative à regarder derrière pour vérifier uniquement pour un seul caractère non espace:
qui est la même que (une version légèrement modifiée d'Aristote pour traiter les espaces et les tabulations comme même afin d'économiser un peu de frappe):
Voir:
et (tout lire!):
Fait ce travail?
%s/[^ ]\zs \+/ /g
dans ce cas (:help /\zs
)J'aime cette version - il est semblable à la regarder de l'avant version d'Aristote Pagaltzis, mais je le trouve plus facile à comprendre. (Probablement juste mon manque de familiarité avec la \zs)
ou pour tous les espaces
Je l'ai lu comme "remplacer toutes les occurences d'autre chose qu'un espace suivi par plusieurs espaces avec le quelque chose, et un seul espace".
\zs
et\ze
, ils peuvent faire des merveilles pour la writability et la lisibilité des motifs plus complexes (en particulier lorsque vous avez raison d'utiliser les deux à la fois!).\zs
et\ze
, mais j'ai aussi souvent utiliser mon regexs en python et sed. De sorte qu'il peut être agréable d'avoir une solution qui fonctionne à travers de multiples applications.Répondu; mais, si j'avais jeter mon flux de travail de toute façon.
Rapide et simple à retenir. Il y a beaucoup plus élégant des solutions ci-dessus; mais, mon .02.