正则表达式在Latex环境之间查找并替换

时间:2019-02-17 12:26:02

标签: regex perl latex

我试图提出一个用于查找和替换的正则表达式,以便可以找到在align环境中使用的所有'('字符。 示例文字:

<?php
class User extends AppModel {

:

public $validate = array(
            'email' => array(
                'rule' => array('email'),
                'message' => 'Invalid format',
            )
}

然后我想在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 \begin{align}内找到所有的'(',而不是在文本主体内找到。到目前为止,我有正则表达式:

\end{align}

但这只能找到环境中的所有文本,而不能找到'('的各个实例。

(这是因为我需要遍历整个文档并将等式内的所有'('更改为'(?<=\{align\})\s(.*)\s(.*)\s(?=\\end\{align\}) ',并且我不想更改文本中出现的任何括号。可以使用。)

2 个答案:

答案 0 :(得分:6)

在标量上下文(即作为触发器)中使用范围运算符(..)隔离要处理的块。

#!/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;

使用您指定的文本进行测试:

$ 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

或者作为单线:

$ 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}
...

如果块检测太严格,即在您的真实文档中\begin\end不在行的开头,请尝试不使用^的以下命令(插入符号):

 if (/\\begin\{align\}/../\\end\{align\}/) {

答案 1 :(得分:5)

有两种技术可以完成给定的任务。一种是从\\begin{align}开始比赛,另一种是发信号通知引擎在面对(之后立即停止匹配\\end{align}

第一步可以使用\G令牌进行,第二步是限制性匹配或回火的工作[^(]

(?:\\begin{align}|\G(?!\A))(?:(?!\\end{align})[^(])*\K\(

请参见live demo here

Perl代码:

my $regex = qr/(?:\\begin{align}|\G(?!\A))(?:(?!\\end{align})[^(])*\K\(/p;
my $subst = '\\\\left(';
my $result = $str =~ s/$regex/$subst/rg;

请参见live demo here

正则表达式细目:

  • (?:非捕获组的开始
    • \\begin{align}从字面上匹配\begin{align}
    • |
    • \G(?!\A)从上一场比赛结束的地方开始比赛
  • )非捕获组的结尾
  • (?:开始NCG
    • (?!\\end{align})直到我们到达\end{align}
    • [^(]尝试匹配非(字符
  • )* NCG结束,请尽可能重复
  • \K\(重置匹配的部分并尝试匹配(

单线:

perl -0777 -i.bak -pe 's~(?:\\begin\{align}|\G(?!\A))(?:(?!\\end\{align})[^(])*\K\(~\\left(~g;' file