Voudrait effectuer une recherche et remplacer dans un fichier de 12000 lignes.
Plus précisément, si une occurrence de ^ SetFontSize 28
existe après un ^Hide
bloc et avant le suivant ^Hide
ou ^Show
, passez 28
à 18
.
Voici un extrait du fichier d'origine.
Hide # Gear - Endgame
ItemLevel >= 77
Rarity = Magic
LinkedSockets >= 3
BaseType "Runic Hatchet"
SetTextColor 140 190 255 # Magic Item Highlight
SetFontSize 28
Hide # Gear - Endgame
ItemLevel >= 77
Rarity = Magic
Sockets >= 3
BaseType "Runic Hatchet"
SetTextColor 140 190 255 # Magic Item Highlight
SetFontSize 28
Show # Gear - Endgame
ItemLevel >= 83
Rarity = Normal
Sockets < 3
BaseType "Tiger Hook"
SetTextColor 240 240 240 # Normal Item Highlight
SetBackgroundColor 70 70 70
SetFontSize 28
Le résultat final pour l'un des Hide
blocs devrait ressembler à ceci:
Hide # Gear - Endgame
ItemLevel >= 77
Rarity = Magic
LinkedSockets >= 3
BaseType "Runic Hatchet"
SetTextColor 140 190 255 # Magic Item Highlight
SetFontSize 18
Remplacement SetFontSize 28
de SetFontSize 18
, mais uniquement s'il apparaît dans un ^Hide
bloc.
Le regex méchant que j'ai essayé était:
:%s/^Hide\(.*\)SetFontSize 28$/Hide\1SetFontSize 18/g
Mais on m'a dit que le motif n'était pas trouvé. Veuillez me faire savoir si des informations supplémentaires sont nécessaires ou si ma demande n'est pas claire.
Hide
bloc a-t-il uneSetFontSize
ligne (quelle que soit la valeur)? Si c'est le cas, vous pouvez utiliser:%s/Hide\_.\{-\}SetFontSize \zs28/18/
whatever be the value
causerait des problèmes, votre solution ne fonctionne que si chaqueHide
bloc a uneSetFontSize
ligne et sa valeur est exactement28
, sinon, elle correspond jusqu'à28
un autre bloc.Réponses:
Une façon de résoudre ce problème serait d'utiliser
:global
un générateur de sortie de plage.L'utilisation typique de la
global
commande seraitIl a également la possibilité de faire en sorte que ce modèle génère une plage plutôt qu'une correspondance sur une seule ligne en utilisant
,
sous la forme deCela génère une plage qui est appliquée à la commande.
Pour exemple , le premier motif serait assortit la première
Hide
entrée et le second motif est soitHide
,Show
ou la fin du fichier ( en supposant que vous voulez que le dernier cas Masquer).La première regex est simple,
/Hide/
. Le deuxième regex contient quelques parties intéressantes.\(
et\)
crée un groupement d'atomes pour correspondre\|
est l'opération OU\%$
représente la fin du fichierUne fois que nous avons défini nos plages, nous appliquons le substitut avec un modèle et une chaîne comme vous le feriez normalement.
Veuillez noter que l'expression régulière utilisée dans cet exemple est très basique. Vous voudrez vous assurer que vos identifiants pour le début et la fin de la plage capturent les bonnes zones.
la source
Il semble que votre regex méchant n'était pas assez méchant ... :-)
Section de recherche
La recherche devrait être modifiée comme suit:
Cela inclut pas mal de choses rares et tant de parenthèses ... Voyons ce que nous avons là-dedans:
Le curseur (
^
)Le caret est utilisé pour signifier le début de la ligne. Je pense que nous connaissons déjà celui-ci.
Un point important, le
^
ne fonctionne que comme le tout premier caractère de votre modèle. Après cela, il est pris mot pour mot. Pour inclure un début de ligne dans votre expression, vous devez utiliser\_^
. Cependant, dans notre situation, nous n'en avions pas besoin.(Il y a un phénomène similaire avec
$
et\_$
)La première et la dernière parenthèse (
\( ... \)
)La première et la dernière parenthèse sont utilisées seules, ce qui signifie qu'il saisira tout ce qui apparaît à l'intérieur et le définira en paramètre
\1
. Vous l'avez déjà utilisé dans votre propre expression régulière, donc je suppose que vous connaissez également celui-ci.Le deuxième ensemble de parenthèses
Comme vous pouvez le remarquer, il existe un deuxième ensemble de parenthèses suivi d'un astérisque
\( ... \)*
. Cela signifie que nous recherchons ce qui correspond un certain nombre de fois. Il s'agit de la manière habituelle d'utiliser l'astérisque, vous devez donc le connaître.Le troisième ensemble de parenthèses, OR, et
\_.
Oui, il y a en fait trois parenthèses devant le mot
Show
. Ce dernier ensemble est nécessaire pour deux raisons: la\|
et la suivante@!
.En ce qui concerne l'opération OR, vous devez déjà la connaître.
L'ordre n'a pas d'importance ici. Le
\
est nécessaire devant le|
pour travailler en vim.La parenthèse autour de cette expression nous permet de suivre l'expression par quelque chose . Voici le
@!
.Celui-ci est beaucoup moins familier. Cela signifie que s'il ne correspond pas . L'utilisation de ceci n'est cependant pas très facile, mais vous devez suivre cette expression avec ce que vous voulez extraire qui ne devrait pas correspondre à ladite expression. C'est pourquoi nous avons
\_.
derrière ce modèle.Les
\_.
moyens correspondent à quoi que ce soit. Contrairement au.
seul, qui ne correspond pas au\n
personnage. En d'autres termes, nous faisons correspondre n'importe quel caractère sur un nombre quelconque de lignes, sauf s'il correspond àShow
ouHide
.Notez que les parenthèses autour de cette expression sont également importantes, tout comme l'astérisque, donc tout cela est vraiment ce qui le fait fonctionner:
alias correspondent tout à la suivante
Show
ou lesHide
caractères (notez que ce serait également correspondreShowing
,Shower
,HideMe
, etc. , vous devriez être en mesure d'utiliser\<
et\>
s'il est nécessaire de faire correspondre exactement le mot.)Note latérale: pour rechercher sur plusieurs lignes, il est également possible d'utiliser le
\n
caractère dans le motif. Cependant, ce n'est pas aussi polyvalent que le\_.
motif.SetFontSize 28
Maintenant, la section doit également inclure
SetFontSize 28
. Tout comme vous l'aviez dans votre expression régulière. Si aucunSetFontSize 28
n'apparaît dans cette section, essayez à nouveau la recherche dans la section suivante.En raison de la négation ci-dessus (la correspondance sauf
Show
ouHide
), la recherche ne passe pas à la section suivante, prenant le risque de la gâcher.Section de remplacement
Le remplacement est le même que vous l'aviez:
Nous utilisons les parenthèses dans la recherche pour que les
\1
travaux fonctionnent comme prévu.Recherche complète et remplacement
Les modèles résultants se présentent comme suit:
Le
\(Show\|Hide\)
devrait inclure tous les en- têtes possibles .Sources
Regex pour correspondre à n'importe quel caractère, y compris la nouvelle ligne (
\_.\{-}
)Recherche de lignes ne contenant pas de motif et autres recherches utiles (
@!
)Documentation Vim: pattern (
\_^
)la source
()*
, ma version de votre réponse:%s/\v^Hide.*\n(\s+.*\n)*\s*SetFontSize\s+\zs28/16
.