非常简单的假设问题,
我已达到 的限制sed
,需要将sed
脚本更改为perl
.所以对于sed
有条件的替换
sed '/condition/ s/xx/yy/'
在perl中如何实现呢?
例如,如何在 perl 中执行以下操作?
seq 6 > /tmp/tf
$ paste -d '' /tmp/tf /tmp/tf | sed -E '/[135]/s/^(.)(.)$/\1.\2-/'
1.1-
22
3.3-
44
5.5-
66
$ paste -d '' /tmp/tf /tmp/tf | perl -pe 's/$&/$1.$2-/ if /^([135])(.)$/'
.-
22
.-
44
.-
66
答案1
如果您的目标是减少打字并增加如何在 Perl 和sed
.在这种情况下,Perlsed
和 Perl 都允许通过指定空表达式来重用最近匹配的正则表达式。
sed '/^\([135]\)\(.\)$/ s//\1.\2-/'
perl -pe '/^([135])(.)$/ && s//$1.$2-/'
命令中的空正则表达式s///
将重用前面测试中的表达式(通常是最近的匹配表达式)。
在 Perl 中,我们必须&&
在测试和替换之间添加,以使其充当短路语句if
。在 中sed
,第一个表达式仅充当地址的替换命令。
一般来说,
sed '/condition/ s/xx/yy/'
...将“相同”(考虑到稍微不同的语法和正则表达式风格)
perl -pe '/condition/ && s/xx/yy/'
但在这种情况下,直接应用替换会更简单:
sed 's/^\([135]\)\(.\)$/\1.\2-/'
perl -pe 's/^([135])(.)$/$1.$2-/'
答案2
问题是,$1
等等在每个新的正则表达式上都会重置,因此除非您在命令中重复它们,否则它们将为空s
,即
s/^([135])(.)$/$1.$2-/ if /^([135])(.)$/'
可以通过删除来简化if
:
s/^([135])(.)$/$1.$2-/
在更一般的情况下,您可以保留捕获的值:
if (/^([135])(.)$/) { $a=$1; $b=$2; s/$&/$a.$b-/; }
答案3
使用乐(以前称为 Perl_6)
raku -pe 's/^ (<[135]>) (.) $/$0.$1-/;'
或者
raku -pe 's/^ (.) (.) $/$0.$1-/ if m/^ <[135]> /;'
#Immediately above being a re-arrangement of:
raku -pe 'if m/^ <[135]> / {s/^ (.) (.) $/$0.$1-/};'
发布此内容是希望它对涉足 Raku 的 Perl 用户有用。在 Raku 中,捕获从 开始$0
,字符类是用<[
…]>
标记创建的(方括号单独保留用于分组)。而且匹配通常对空格不敏感(即 Perl5 的\x
默认值)。
尝试 @Kusalananda 的第一个 Perl5 代码示例(如上所述带有 Raku '重音')将产生 Raku 错误Null regex not allowed
。因此,上面的第一个 Raku 答案看起来更像@Kusalananda 的最后的Perl5 代码示例。 (上面的第二个 Raku 答案使用了if
条件,一些用户可能会发现它更具可读性)。
输入示例:
11
22
33
44
55
66
示例输出:
1.1-
22
3.3-
44
5.5-
66
附录:由于OP发布了连接的示例数据完全相同的数字——我想知道这里是否还有一个未解答的问题反向引用。在 Raku 中,如果您想重复使用匹配中的第一个捕获(例如运算符的左侧s///
),您可以执行以下操作:
raku -pe 's/^ (<[135]>) $0 $/$0.$0-/;'
或者
raku -pe 's{^ (<[135]>) $0 $} = "$0.$0-";'
或(命名捕获,如下):
raku -pe 's/^ $<myOdd>=<[135]> $<myOdd> $/$<myOdd>.$<myOdd>-/;'
或者
raku -pe 's{^ $<myOdd>=<[135]> $<myOdd> $} = "$<myOdd>.$<myOdd>-";'
上面的第二个和第四个示例使用 Raku 的新“替换赋值”表示法,该表示法(为了增强可读性)还允许使用各种分隔符 - 括号、花括号等(当然,if
可以使用单独的条件,如前面所示)部分,但这可能会导致代码可读性较差)。
https://raku.org/archive/rfc/144.html
https://raku.org/archive/rfc/331.html
https://raku.org