Regexp multilignes dans emacs.

Pour transformer tous les passages du type

$$
blah blah
$$

en

\[
blah blah
\]

mon souci majeur était que, dans les expressions régulières d’emacs, le point (« . ») ignore les fin de ligne, et donc « .* » s’arrête en fin de ligne plutôt que de continuer.

Internet étant mon ami [1], j’ai rapidement trouvé comment contourner le soucis. La première solution (voir plus loin pour une solution plus courte), est la suivante :

\$\$\(\(.*\|^J*\)*?.*?\)\$\$ devient \\[\1\\]

(^J s’obtient en faisant C-q C-j)

Explications :

  • \$\$ est clair.
  • \( entame le premier groupe, et dedans je mets
  • \(.*\|^J*\)*? qui prend des lignes complètes, fin de ligne comprise, autant que nécessaires (le ? force l’arrêt dès que possible : lazy versus greedy), ensuite
  • .*? indique de prend des caractères quelconques, autant que nécessaire
  • \) fin du groupe, il sera désigné par \1
  • \$\$ parle de lui même.

Chose étrange, il semblerait que parfois, sans raison, il y ait un plantage : emacs ne réagit plus, et pas moyen de confirmer le remplacement du texte (j’utilise query-replace-regexp). Seul C-g vient à mon secours.
Lorsque ça arrive sur des zones un peu plus longues (formule de math de plusieurs lignes), j’enlève quelques fins de lignes et ça va mieux (mais il m’est arrivé que ça marche, puis de faire Undo, puis de retenter… et que ça ne marche plus ! Pourtant le undo me remet juste avant le remplacement, donc les conditions devraient être les mêmes !)
Lorsque j’ai le même problème sur des formules plus courtes, ben je ne sais pas… j’ai tenté de copier/coller la formule dans le buffer scratch, et là ça marchait… en revenant à mon fichier, ça ne marchait pas. J’ai fait M-x debug au hasard, puis j’ai retenté la manip (pensant que ça m’afficherait un message d’erreur, mais je me suis fourvoyé sur le fonctionnement de debug) et là ça a marché. Bref, au petit bonheur…

Ceci dit, j’ai trouvé une autre référence [2], qui m’a permis de choper une autre regexp :

\$\$\([^^@]*?\)\$\$ devient \\[\1\\]

qui semble mieux fonctionner. Ici, ^ est un « ^ » normal, et « ^@ » est le « null-character » obtenu en faisant C-q 0 RET
(ici « 0  » est le code, en octal, du caractère null)

Références:
[1] http://www.emacswiki.org/emacs-ja/MultilineRegexp
[2] http://www.zzamboni.org/brt/2007/03/27/how-to-match-multi-line-regular-expressions-in-emacs-lisp/index.html

Étiquettes : ,

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s


%d blogueurs aiment cette page :