使用 sed 替换为第一个匹配字符

使用 sed 替换为第一个匹配字符

尝试更新一些乳胶代码。四行:

something $^\text{TT}$ and more stuff
something $^\text{T}$ and more stuff
something $^\text{M\times N}$ and more stuff
something $^\text{T} {otherstuff}$

应该变成

something $^{\text{TT}}$ and more stuff
something $^{\text{T}}$ and more stuff
something $^{\text{M\times N}}$ and more stuff
something $^{\text{T}} {otherstuff}$

换句话说,用额外的 . 将上标括起来{...}

我的尝试使用sed如下

sed 's/\^\\text{\(.*\)}/\^{\\{text{\1}}/' testregex

这适用于前三行,但最后一行不起作用并产生

something $^{\text{T} {otherstuff}}$

反而。问题是sed与每行的最后一个匹配},但我需要它匹配}后面的第一个\text{

另外,如果这可以在同一行上多次工作,那就太好了,例如,

^\text{1} la la la ^\text{2}

应该变成

^{\text{1}} la la la ^{\text{2}}

我确信只需进行一点小小的修改即可使其工作,但我无法弄清楚,这让我发疯。提前致谢!

答案1

克服贪婪正则表达式问题的一种方法是显式查找一串非分隔符,后跟分隔符。同时,您可以通过以下方式简化替换语法:

sed 's/\^\(\\text{[^}]*}\)/\^{\1}/' input.tex 

应该可以使用

sed 's/\^\(\\text{[^}]*}\)/\^{\1}/g' input.tex 

每行有多个匹配项。

答案2

你快到了!不要\text{}像使用 一样在块内查找“0 个或多个字符” \\text{\(.*\)},而是查找“0 个或多个非}字符”:

$ sed 's/\^\\text{\([^}]*\)}/\^{\\{text{\1}}/g' foo.tex 
something $^{\{text{TT}}$ and more stuff
something $^{\{text{T}}$ and more stuff
something $^{\{text{M\times N}}$ and more stuff
something $^{\{text{T}} {otherstuff}$

添加到末尾的Ig打开全局匹配,这意味着该行上的所有匹配都将被替换。请注意,这假设匹配不重叠,它不适用于以下情况:

something $^{\{text{$^{\{text{BB}}$}}$ and more stuff

我假设这在这里不是问题。

答案3

我建议这样:

$ sed 's/\$\^\\\([^}]*\)/$^\{\\\1}/' file
something $^{\text{TT}}$ and more stuff
something $^{\text{T}}$ and more stuff
something $^{\text{M\times N}}$ and more stuff
something $^{\text{T}} {otherstuff}$

相关内容