sed似乎只有在插入换行符时才能正确匹配模式

时间:2015-09-21 13:42:24

标签: sed

我目前正在运行以下sed命令:

sed 's/P(\(.*\))\\mid(\(.*\))/\\condprob{\1}{\2}/g' myfile.tex

基本上,我继承了一个奇怪格式化的tex文件,并希望替换这样的所有内容:

P(<foo>)\mid(<bar>)

有了这个

\condprob{<foo>}{<bar>}

我尝试运行sed的文件包含以下行:

P(\vec{m}_i)\mid(t,h,\alpha) = \prod_{u\in\mathcal{U}} P(\vec{m}_{iu})\mid(t,h,\alpha)

我想改为:

\condprob{\vec{m}_i}{t,h,\alpha} = \prod_{u\in\mathcal{U}}\condprob{\vec{m}_{iu}}{t,h,\alpha}

但是,sed会错过第一个\ mid而不是给我这个:

\condprob{\vec{m}_i)\mid(t,h,\alpha) = \prod_{u\in\mathcal{U}} P(\vec{m}_{iu}}{t,h,\alpha}

如果我在=符号处添加换行符,则匹配一切正常

有人可以请a)帮我解决这个问题,b)或许告诉我它为什么会这样?

感谢。

编辑:感谢choroba和Sloopjon,你们都回答了我的原因,而且Sloopjon的解决方案实际上正是我所需要的。 choroba:我想我将不得不再等一天来学习perl。

对于那些对Sloopjon的解决方案感兴趣的人,在翻译成我的问题时看起来像这样(匹配所有不是一个右括号):

sed 's/P(\([^)]*\))\\mid(\([^)]\))/\\condprob{\1}{\2}/g' myfile.tex

2 个答案:

答案 0 :(得分:2)

您希望P(\(.*\))仅匹配P(\vec{m}_i),但*量词是贪婪,因此它实际上与P(\vec{m}_i)\mid...P(\vec{m}_{iu})匹配。有两种常见的解决方法:如果您的工具支持它,请使用非贪婪的量词,或者更改模式以使其仅与您期望的匹配。例如,如果您知道括号不会嵌套在此P()构造中,请将.*更改为[^)]*

编辑:我还建议你在遇到这样的问题时寻找正则表达式可视化工具或调试器。例如,将您的示例粘贴到debuggex.com可以清楚地了解发生了什么。

答案 1 :(得分:1)

问题是*量词的贪婪。它尽可能多地匹配,即它不会在第一个)停止。

你可以尝试Perl,它具有“非贪婪”(节俭,懒惰)*?

perl -pe 's/P\((.*?)\)\\mid\((.*?)\)/\\condprob{$1}{$2}/g'