我试图提出一个用于查找和替换的正则表达式,以便可以找到在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\})
',并且我不想更改文本中出现的任何括号。可以使用。)
答案 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\(
Perl代码:
my $regex = qr/(?:\\begin{align}|\G(?!\A))(?:(?!\\end{align})[^(])*\K\(/p;
my $subst = '\\\\left(';
my $result = $str =~ s/$regex/$subst/rg;
正则表达式细目:
(?:
非捕获组的开始
\\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