ed 中的子表达式用于多次替换

ed 中的子表达式用于多次替换

假设我有一段文字说:

John went with Sally to the market where they bought fresh bread. There they met with Jim and dined together.

假设我想编写一个正则表达式,用加号将 John、Sally 和 Jim 的名字括起来,如下所示:

+John+ went with +Sally+ to the market where they bought fresh bread. There they met with +Jim+ and dined together.

我创建了以下正则表达式,成功将​​第一个名称更改为 +John+:

g/\(.*\)\(\<John\>\)\(.*\)/s//\1+\2+\3/gp

我想创建一个一次性替换所有三个名称的名称,而不需要重新运行命令。

我尝试了简单的多重替换,例如:

g/John/s//+&+/\
s/Sally/+&+/\
s/Jim/+&+/p

但这仅改变了每个名字的第一个实例。

答案1

您的编辑命令是几乎正确的。

g/./ s/John/+&+/g\
s/Sally/+&+/g\
s/Jim/+&+/gp

这里有两个主要变化:

  1. 该命令使用的正则表达式g需要与我们可能想要应用命令列表的所有行相匹配。您使用了John,这意味着除非同一行上有 a ,Sally否则不会更改为。+Sally+John

    .在这里使用来选择所有非空行,但您也可以使用例如^$来选择全部线。使用这样的方式可能更有意义...,以便我们选择足够长的行来包含字符串Jim(三个名称中最短的一个)。

  2. 我正在使用该g标志每个三个s///命令中的一个,用于对每行上的每个非重叠匹配项进行替换。我正在使用gp最后一个替换,但只是因为您自己这样做了,以查看命令的效果。

如果您需要将其与类似字符串区分开来\<John\>,并且系统 C 库的基本正则表达式 (BRE) 支持它,请使用 in 代替(这也适用于在 BRE 中使用 (alterations) 之类的内容,这是非标准的,但这将允许你在 GNU 系统上编写)。JohnJohnny\|g/./ s/John\|Sally\|Jim/+&+/gp

答案2

怎么样:

1,$g/./s/John/+&+/g;s/Sally/+&+/g;s/Jim/+&+/g

在你的第一个中s,你有g后缀。如果你像这样把它放在第二个中,那么每个替补将执行所有发生的事情,而不仅仅是第一个。

相关内容