我有一个文件 test.txt,其中包含,
home -> range
如果我在 vim 中编辑文件并运行命令,%s/^\(.*\)->\(.*\)$/\2 ::= \1 ;/g
它会将文件转换为
range ::= home ;
这正是我想要的。但是如果我运行
perl -pi -e 's/^\(.*\)->\(.*\)$/\2 ::= \1 ;/g' test.txt
我认为应该做同样的事情,但我没有得到任何变化 - 有人能告诉我出了什么问题吗?我怀疑有些东西需要转义,但我已经尝试了各种转义组合……另外,我想要一些关于两种格式之间转换的一般规则……
答案1
在 Perl 中,您不需要转义捕获括号,并且通常使用 $1,$2 而不是 \1,\2 作为捕获变量。
perl -pi -e 's/^(.*)->(.*)$/$2 ::= $1 ;/g' test.txt
生活中一个不幸的事实是正则表达式许多常用工具(vim、sed、awk、perl)中使用的 RE 都略有不同。有些工具可以选择使用 Perl RE、POSIX 基本 RE(BRE)或 POSIX 扩展 RE(ERE)。
perldoc perlre
在替换表达式的替换部分中对$1
vs有这样的说法\1
有些人已经习惯了这样写:
$pattern =~ s/(\W)/\\\1/g;
为了避免让 sed 的狂热爱好者感到震惊,RHS 的替代品保留了这一点,但养成这种习惯是件坏事。这是因为在 PerlThink 中,“s///”的右侧是双引号字符串。通常的双引号字符串中的“\1”表示 Control-A。“\1”的惯用 Unix 含义被临时替换为“s///”。但是,如果您养成了这样做的习惯,那么如果您随后添加“/e”修饰符,您就会陷入麻烦。