上下文感知正则表达式

时间:2017-03-20 15:36:49

标签: regex bash grep

我有一个很长的Latex文档,并且已被要求用小写字母a更改数学符号大写字母A的每个外观。

唯一的问题是这个符号在乳胶数学表达式中重复了很多次(我猜超过300)。它也会在单个表达式中出现多次。

我想手动修复这个需要付出相当大的努力,更不用说我肯定会忽略许多替代品。另外,请注意正常"查找/替换"标准编辑器的功能在这里是不可能的,因为字母A(不是数学符号A)几乎出现在文档的任何地方。

所以我认为正则表达式是解决我问题的好方法;但是,我需要确保我做得对,这是这篇文章的主要原因。我很感激,如果有人可以看看下面的正则表达式,并告诉我可能出现的问题以及如何解决它。

首先,我需要列出我想用grep修复的地方,所以我写道:

$ # list all the occurrences of "A" inside latex math environment
$ # i.e., surrounded by $ $ 
$ # Note that since $ is a special char in regex, we have to escape it
$ grep -n '\$[^\$]*A[^\$]*\$' doc.tex

这个grep按预期工作,但不是我想要的。为了说明这个问题,请考虑以下简单示例:

$ cat -n test.tex 
     1  Abc $y_1=A x$. 
     2  Abc $y_2=b x$. Abc $c^2$.
     3  Abc $y_2=b x$.
     4  Abc $y_1=A x$. 
     5  abc $y_1=x$.
     6  abc abc. $E=mc^2$.
$ grep -n '\$[^\$]*A[^\$]*\$' test.tex 
1:Abc $y_1=A x$. 
2:Abc $y_2=b x$. Abc $c^2$.
4:Abc $y_1=A x$.

第2行由grep显示,但我不希望这种情况出现,因为匹配的A在数学环境的分隔符之外。是否可以修复此正则表达式,以避免类似于第二次匹配的情况?我想我的问题可以概括为问正则表达式是否有可能意识到它的背景?

如果我想到解决问题的方法,我会建议以下"抽象概念":

 B = TRUE 
 For every match that grep finds
     If B is TRUE 
        Display the match
     End if
     B = not B
 End for

换句话说,当grep找到匹配项时,只有当B为TRUE时才显示它,反转B,并重复所有匹配。

这个想法应该有用,因为我没有在我的文档中嵌套数学表达式。那么我们可以用grep实现这个想法吗?或者还有什么更好的主意吗?

1 个答案:

答案 0 :(得分:2)

我会尝试:

perl -pnE 's/ (\$.*?\$) / $1 =~ s:A:a:gr /xge'
  • 搜索dollar 文字 dollar(例如数学表达式)
  • 并且每对内部改变A - >;一个
  • 重复下一对
  • 这些对显示为mmmmm

e.g。从

Abc $y_2=A A x$. A A $c^2$. Ab A $y_1=AaA x$. A $ dol
____mmmmmmmmmmm______mmmmm_______mmmmmmmmmmm_________ 
# the  m shows the matched pairs e.g. the "inside of the math expr"

产生

Abc $y_2=a a x$. A A $c^2$. Ab A $y_1=aaa x$. A $ dol

EDIT2 - 用于多行和荣誉转义\$

允许多行需要稍微不同:

perl -0 -pE' s /(\ $。*?\ $)/ $ 1 = ~s:A:a:gr / xges' file.lat
perl -0 -pE 's/ (?<!\\) (\$ .*? (?<!\\) \$) / $1 =~ s:A:a:gr /xges'
  • -0&#34; slurps&#34;将整个文件转换为perl
  • 并添加了s修饰符
  • \$
  • 使用负面后视

来自输入的演示

Abc $y_1=A x$. 
Abc $y_2=b x$. Abc $c^2$. $y_1=A x$.
Abc $y_2=b x$.
Abc $y_1=A x
      still AAA inside multi line
      math AAA end->$. A-outside here
 in \$ still in AAA out \$ still out.
still A outside $ Again A AA inside
multi  up to \$ still AA inside
here $ A out
abc $y_1=x$.
abc abc. $E=mc^2$.

产生

Abc $y_1=a x$. 
Abc $y_2=b x$. Abc $c^2$. $y_1=a x$.
Abc $y_2=b x$.
Abc $y_1=a x
      still aaa inside multi line
      math aaa end->$. A-outside here
 in \$ still in AAA out \$ still out.
still A outside $ again a aa inside
multi  up to \$ still aa inside
here $ A out
abc $y_1=x$.
abc abc. $E=mc^2$.

Ps:对不起,我有限的英语没有更详细的解释......