Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Regex find and replace inbetween Latex enviroment

Tags:

regex

perl

latex

I'm trying to come up with a regex to use in find and replace so I can find all '(' characters used inside of the align environment. Example text:

Lorem Ipsum Lorem Ipsum Lorem Ipsum 
Lorem Ipsum Lorem Ipsum (Lorem Ipsum Lorem Ipsum )
Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum 
\begin{align}
\frac{d_l}{2}< |\epsilon_H(g(m))| <\frac{d_r}{2} 
\frac{d_l}{2}< |\epsilon_H(g(m))| <\frac{d_r}{2} 
\end{align}
Lorem Ipsum Lorem Ipsum Lorem Ipsum 
Lorem Ipsum Lorem Ipsum Lorem Ipsum 

I then want to find all the '(' inside of \begin{align} and \end{align}and NOT inside the main body of text. I so far have the regex:

(?<=\{align\})\s(.*)\s(.*)\s(?=\\end\{align\})

but this only finds ALL the text inside the environment and not the individual instances of '('.

(The reason behind this is because I need to go through my whole document and change all the '(' inside the equations to '\left(' and I don't want to change any parentheses occurring in the text that may be used.)

like image 633
Sam Palmer Avatar asked Dec 17 '22 18:12

Sam Palmer


1 Answers

Use the range operator (..) in scalar context, i.e. as flip-flop, to isolate the blocks you want to work on.

#!/usr/bin/perl
use strict;
use warnings;

while (<STDIN>) {
    if (/^\\begin\{align\}/../^\\end\{align\}/) {
        # replace all occurences of "(" with "\left("
        s/\(/\\left(/g;
    }
    print;
}

exit 0;

Test run with your given text:

$ perl dummy.pl <dummy.txt
Lorem Ipsum Lorem Ipsum Lorem Ipsum
Lorem Ipsum Lorem Ipsum (Lorem Ipsum Lorem Ipsum )
Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum
\begin{align}
\frac{d_l}{2}< |\epsilon_H\left(g\left(m))| <\frac{d_r}{2}
\frac{d_l}{2}< |\epsilon_H\left(g\left(m))| <\frac{d_r}{2}
\end{align}
Lorem Ipsum Lorem Ipsum Lorem Ipsum
Lorem Ipsum Lorem Ipsum Lorem Ipsum

Or as one-liner:

$ perl <dummy.txt -pe 's/\(/\\left(/g if (/^\\begin\{align\}/../^\\end\{align\}/)'
...
\frac{d_l}{2}< |\epsilon_H\left(g\left(m))| <\frac{d_r}{2}
\frac{d_l}{2}< |\epsilon_H\left(g\left(m))| <\frac{d_r}{2}
...

If the block detection is too strict, i.e. in your real document the \begin and \end are not at the beginning of the line, then try the following without the ^ (caret):

 if (/\\begin\{align\}/../\\end\{align\}/) {
like image 74
Stefan Becker Avatar answered Dec 30 '22 22:12

Stefan Becker