Me gustaría realizar una búsqueda y reemplazar en un archivo con 12000 líneas.
Específicamente, si ^ SetFontSize 28
existe una aparición después de un ^Hide
bloque y antes del siguiente ^Hide
o ^Show
, cambie 28
a 18
.
Aquí hay un fragmento del archivo original.
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
El resultado final para uno de los Hide
bloques debería verse así:
Hide # Gear - Endgame
ItemLevel >= 77
Rarity = Magic
LinkedSockets >= 3
BaseType "Runic Hatchet"
SetTextColor 140 190 255 # Magic Item Highlight
SetFontSize 18
Reemplazar SetFontSize 28
a SetFontSize 18
, pero solo si aparece en un ^Hide
bloque.
La expresión regular desagradable que probé fue:
:%s/^Hide\(.*\)SetFontSize 28$/Hide\1SetFontSize 18/g
Pero se le dijo patrón no encontrado. Avíseme si necesita información adicional o si mi solicitud no está clara.
Hide
bloque tiene unaSetFontSize
línea (cualquiera que sea el valor)? Si es así, podría usar:%s/Hide\_.\{-\}SetFontSize \zs28/18/
whatever be the value
causaría problemas, su solución solo funciona si cadaHide
bloque tiene unaSetFontSize
línea y su valor es exactamente28
, de lo contrario, coincide hasta que aparezca28
otro bloque.Respuestas:
Una forma de resolver esto sería usar
:global
un generador que genere una salida de rango.El uso típico del
global
comando seríaTambién tiene la opción de hacer que este patrón genere un rango en lugar de una sola coincidencia de línea mediante el uso
,
deEsto genera un rango que se aplica al comando.
Por su ejemplo el primer patrón se pongan en venta la primera
Hide
entrada y el segundo patrón es cualquieraHide
,Show
o al final del archivo (asumiendo que usted quiere que el último caso Ocultar).La primera expresión regular es simple,
/Hide/
. La segunda expresión regular contiene algunas partes interesantes.\(
y\)
crea una agrupación de átomos para que coincida\|
es la operación OR\%$
representa el final del archivoUna vez que hemos definido nuestros rangos, aplicamos el sustituto con un patrón y una cadena como lo haría normalmente.
Tenga en cuenta que la expresión regular utilizada en este ejemplo es muy básica. Deberá asegurarse de que sus identificadores para el principio y el final del rango capturen las áreas correctas.
fuente
Parece que tu desagradable expresión regular no era lo bastante desagradable ... :-)
Sección de búsqueda
La búsqueda tendría que cambiarse a esto:
Esto incluye bastantes cosas poco comunes y tantos paréntesis ... Veamos qué tenemos allí:
El Caret (
^
)El símbolo de intercalación se usa para indicar el comienzo de la línea. Creo que ya estamos familiarizados con este.
Un punto importante, el
^
no funciona, excepto como el primer personaje en su patrón. Después se toma al pie de la letra. Para incluir un comienzo de línea dentro de su expresión, debe usar\_^
. Sin embargo, en nuestra situación no necesitábamos eso.(Hay un fenómeno similar con
$
y\_$
)El primer y último paréntesis (
\( ... \)
)El primer y último paréntesis se usan por sí mismos, lo que significa que tomará lo que aparezca dentro y lo establecerá en parámetro
\1
. Ya lo usó en su propia expresión regular, por lo que supongo que también está familiarizado con este.El segundo conjunto de paréntesis
Como puede observar, hay un segundo conjunto de paréntesis seguido de un asterisco
\( ... \)*
. Esto significa que estamos buscando lo que coincida varias veces. Esta es la forma habitual de usar el asterisco, por lo que debe estar familiarizado con él.El tercer conjunto de paréntesis, OR, y
\_.
Sí, en realidad hay tres paréntesis antes de la palabra
Show
. Este último conjunto es necesario por dos razones: la\|
y la siguiente@!
.Con respecto a la operación OR, ya debería estar familiarizado con ella.
El orden no importa aquí. El
\
es necesaria frente a la|
de trabajo en vim.El paréntesis alrededor de esta expresión nos permite seguir la expresión por algo . Aquí el
@!
.Este es mucho menos familiar. Significa si no coincide . Sin embargo, el uso de esto no es muy fácil, pero debe seguir esa expresión con lo que desea extraer que no debe coincidir con dicha expresión. Es por eso que tenemos
\_.
detrás de ese patrón.Los
\_.
medios coinciden con cualquier cosa. Al contrario de lo.
que ocurre por sí solo, que no coincide con el\n
personaje. En otras palabras, hacemos coincidir cualquier carácter en cualquier número de líneas a menos que coincida conShow
oHide
.Tenga en cuenta que el paréntesis alrededor de esa expresión también es importante, como lo es el asterisco, por lo que todo esto es realmente lo que lo hace funcionar:
aka coinciden con lo que sea hasta el siguiente
Show
oHide
caracteres (nota que también coincidiríaShowing
,Shower
,HideMe
, etc Usted debe ser capaz de utilizar\<
y\>
si es necesario para que coincida con la palabra exacta.)Nota al margen: para buscar en varias líneas, también es posible usar el
\n
carácter en el patrón. Sin embargo, no es tan versátil como el\_.
patrón.SetFontSize 28
Ahora la sección tiene que incluir
SetFontSize 28
también. Tal como lo tenías en tu expresión regular. Si noSetFontSize 28
aparece en esa sección, intente la búsqueda nuevamente en la siguiente sección.Debido a la negación anterior (la coincidencia excepto
Show
oHide
) la búsqueda no se filtra a la siguiente sección, con el riesgo de estropearla.Sección de reemplazo
El reemplazo es el mismo que tenía:
Usamos el paréntesis en la búsqueda para que
\1
funcione como se esperaba.Búsqueda completa y reemplazo
Los patrones resultantes son así:
El
\(Show\|Hide\)
debe incluir todos los encabezados posibles .Fuentes
Regex para que coincida con cualquier personaje, incluida la nueva línea (
\_.\{-}
)Busque líneas que no contengan patrones y otras búsquedas útiles (
@!
)Documentación de Vim: patrón (
\_^
)fuente
()*
, mi versión de su respuesta:%s/\v^Hide.*\n(\s+.*\n)*\s*SetFontSize\s+\zs28/16
.