Me encanta Emacs, y como me encanta Emacs, no paro de aprender todos los días cosas nuevas. Una de esas cosas nuevas, que más me ha llamado la atención es, como dice el título, la posibilidad de hacer pequeñas operaciones matemáticas al reemplazar texto en Emacs. En concreto, dentro de las expresiones regulares.
Esto, en la práctica serán sumas o restas, o cualquier operación que podemos hacer a los números que encontramos en una expresión regular. Aunque, si nos lo curramos mucho, podremos hacer muchas más cosas (y muy interesantes)
Para más información con las expresiones regulares y con cómo utilizarlas en Emacs, pulsar sobre los enlaces que acabo de poner.
Lo básico
Cuando queremos buscar y reemplazar texto en Emacs, lo hacemos de la siguiente manera:
- M-x replace-string
- Escribimos el texto a buscar y pulsamos enter
- Escribimos el texto por el que queremos reemplazar y pulsamos enter
Cuando queremos hacerlo con una expresión regular escribimos:
- M-x replace-regexp
- Escribimos la expresión regular, y pulsamos enter
- Escribimos el texto de destino y pulsamos enter
Aunque es cierto que el texto de destino admite ciertas expresiones. Por ejemplo si ponemos entre paréntesis (escapados) parte de la expresión, podemos hacer referencia a la misma escribiendo \1, \2, \3... dependiendo de la posición de esa expresión en el texto global, por ejemplo, partiendo de este texto:
http://totaki.com/
https://totaki.com/
Podemos hacer:
- M-x replace-regexp (enter)
- \(https?://\)[a-z\./]+ (enter)
- \1google.com/ (enter)
Y cambiará la dirección de la web respetando el http o https.
A continuación, vamos a aprovechar esta característica para introducir pequeñas expresiones en Emacs lisp que nos ayuden a reemplazar texto, a partir de algún ejemplo práctico.
Incrementar números
Imaginad un texto muy grande, de este estilo:
Tenemos varios artículos, y, de repente, tenemos que meter un artículo en medio. Por ejemplo, entre el 2 y el 3, que debe ser Artículo 3, es decir, tendremos que cambiar los números de todos los artículos, el 3 será el 4, el 4 será el 5, el 5 será el 6, y de ahí hasta el final de nuestro documento. Podemos hacerlo de forma sencilla situándonos debajo del Artículo 2, y haciendo:
- M-x replace-regexp (enter)
- Artículo \([0-9]+\) (enter)
- Artículo \,(+ 1 \#1) (enter)
En donde, en la expresión le decimos que \1 es un número, y queremos sumarle 1. Aunque si no queremos escribir de nuevo la palabra Artículo, podríamos haber hecho:
Diciéndole que el número es la segunda expresión entre paréntesis y la primera palabra la queremos tal cual.
Os dejo el lorem ipsum para practicar:
Artículo 1
----------
Lorem ipsum ad his scripta blandit partiendo, eum fastidii accumsan euripidis in, eum liber hendrerit an.
Qui ut wisi vocibus suscipiantur, quo dicit ridens inciderint id. Quo mundi lobortis reformidans eu,
legimus senserit definiebas an eos. Eu sit tincidunt incorrupte definitionem, vis mutat affert percipit
cu, eirmod consectetuer signiferumque eu per. In usu latine equidem dolores. Quo no falli viris intellegam,
ut fugit veritus placerat per.
Artículo 2
----------
Ius id vidit volumus mandamus, vide veritus democritum te nec, ei eos debet libris consulatu. No mei ferri
graeco dicunt, ad cum veri accommodare. Sed at malis omnesque delicata, usu et iusto zzril meliore. Dicunt
maiorum eloquentiam cum cu, sit summo dolor essent te. Ne quodsi nusquam legendos has, ea dicit voluptua
eloquentiam pro, ad sit quas qualisque. Eos vocibus deserunt quaestio ei.
Artículo 3
----------
Blandit incorrupte quaerendum in quo, nibh impedit id vis, vel no nullam semper audiam. Ei populo graeci
consulatu mei, has ea stet modus phaedrum. Inani oblique ne has, duo et veritus detraxit. Tota ludus oratio
ea mel, offendit persequeris ei vim. Eos dicat oratio partem ut, id cum ignota senserit intellegat. Sit inani
ubique graecis ad, quando graecis liberavisse et cum, dicit option eruditi at duo. Homero salutatus suscipiantur
eum id, tamquam voluptaria expetendis ad sed, nobis feugiat similique usu ex.
Artículo 4
----------
Eum hinc argumentum te, no sit percipit adversarium, ne qui feugiat persecuti. Odio omnes scripserit ad est, ut
vidit lorem maiestatis his, putent mandamus gloriatur ne pro. Oratio iriure rationibus ne his, ad est corrumpit
splendide. Ad duo appareat moderatius, ei falli tollit denique eos. Dicant evertitur mei in, ne his deserunt
perpetua sententiae, ea sea omnes similique vituperatoribus. Ex mel errem intellegebat comprehensam, vel ad
tantas antiopam delicatissimi, tota ferri affert eu nec. Legere expetenda pertinacia ne pro, et pro impetus
persius assueverit.
Artículo 5
----------
Ea mei nullam facete, omnis oratio offendit ius cu. Doming takimata repudiandae usu an, mei dicant takimata id,
pri eleifend inimicus euripidis at. His vero singulis ea, quem euripidis abhorreant mei ut, et populo iriure vix.
Usu ludus affert voluptaria ei, vix ea error definitiones, movet fastidii signiferumque in qui.
Cadena de sumas
Ahora tenemos lo siguiente:
Bueno, y queremos hacer las sumas:
Por lo tanto sustituimos la expresión por el primer término entre paréntesis, el signo +, el segundo término entre paréntesis y la suma de los dos términos.
Palabras en mayúscula
Volviendo al texto de lorem ipsum, queremos poner en mayúscula todas las palabras de dos letras cuya siguiente palabra empiece por vocal, pues bien, podemos hacer lo siguiente:
- M-x replace-regexp (enter)
- \([a-z][a-z]\) \([aeiou]\) (enter)
- \,(upcase \1) \2 (enter)
Ahora hemos utilizado la función upcase de Emacs Lisp que pasa a mayúscula un texto.
La joya de la corona, migrando backups de WordPress
Bueno, algo más práctico, para cuando no tienes plugins instalados y eres como yo, que instalo Emacs en los servidores para utilizarlo remotamente. Tienes un dump de la base de datos de un WordPress, y te das cuenta de que el tema o los plugins están tan bien hechos que guardan un montón de veces la URL de la web donde tienes el wordpress actualmente, pero serializado en PHP.
Es decir, encuentras expresiones de este estilo:
Y muchas veces... si vemos los arrays serializados en PHP, podemos ver que cuando encontramos una cadena en una posición veremos:
s:[tamaño de la cadena]:"TEXTO DE MI CADENA"
Y si has trabajado con WordPress sabrás que no es tan fácil como cambiar un texto por otro. Es decir, si quiero cambiar urldemiwordpress.com por otro dominio, a no ser que este nuevo dominio tenga la misma cantidad de letras que el antiguo, no puedo reemplazar un texto por otro.
Para hacer bien el reemplazo, debería cambiar la dirección y actualizar el número que tengo después de la s, es decir:
s:66:"http://urldemiwordpress.com/wp-content/uploads/2016/01/slider2.jpg"
debo cambiarlo por
s:58:"http://nuevaurl.com/wp-content/uploads/2016/01/slider2.jpg"
y, claro está, cada vez el número que tenemos que poner será diferente.
Pues con emacs, podemos hacer rápidamente este cambio:
- urldemiwordpress.com - nuevaurl.com (8 letras menos)
- M-x replace-regexp (enter)
- \([0-9]+\):\"http://urldemiwordpress.com (enter)
- \,(+ -8 \#1):"http://nuevaurl.com (enter)
Y ya tendremos todos los serializados listos, sólo habría que sustituir los que no están serializados (pero eso con replace-string sale rápido) y algún que otro serializado que tenga algún texto extra, pero con una expresión parecida está hecho.
Foto principal: earlColour