Perl regexp替换 - 多个匹配

时间:2015-12-01 11:32:02

标签: regex perl string-substitution

需要替换正则表达式的一些帮助。 我有一个字符串

;;;;;;;;;;;;;

我需要用

替换它
;\N;\N;\N;\N;\N;\N;\N;\N;\N;\N;\N;\N;

我试过

s/;;/;\\N/;/g

但它给了我

;\N;;\N;;\N;;\N;;\N;;\N;;

试图摆弄前瞻和后视,但无法解决问题。

2 个答案:

答案 0 :(得分:4)

我不会使用正则表达式,而是使用split

#!/usr/bin/env perl
use strict;
use warnings;

my $str = ';;;;;;;;;;;;;'; 

print join ( '\N', split ( //, $str ) );

分割空值,获取每个字符,并利用连接在字符之间放置分隔符这一事实。 (所以不是在第一次之前,而是在最后之后)。

这给出了:

 ;\N;\N;\N;\N;\N;\N;\N;\N;\N;\N;\N;\N;

我认为哪个符合你想要的输出?

作为oneliner,这将是:

perl -ne 'print join ( q{\N}, split // )'

注意 - 我们需要单引号'而不是\N周围的两倍,因此它不会被插值。

如果您需要处理可变内容(例如,不只是;),您可以将grepmap添加到组合中 - 我需要一些示例数据来为您提供虽然有一个有用的答案。

  

我用它进行infile编辑,正则表达式更适合我

继续之后 - perl非常聪明。它允许您进行就地编辑(如果这是您所指的),而无需坚持使用正则表达式。

传统上你可能会这样做

perl -i.bak -p -e 's/something/somethingelse/g' somefile

这样做是将它扩展到循环中:

LINE: while (defined($_ = <ARGV>)) {
    s/someting/somethingelse/g;
}
continue {
    die "-p destination: $!\n" unless print $_;
}

E.g。它实际做的是:

  • 打开文件
  • 按行迭代
  • 转换行
  • 打印新行

使用-i将打印重定向到新文件名。

你不必将自己限制在-p - 产生输出的任何东西都会以这种方式运作 - 尽管如果它没有通过&#39,请记住;它没有修改的任何行(正则表达式转换)它会丢失数据。

但你绝对可以做到:

perl -i.bak -ne 'print join ( q{\N}, split // )'

并进行内部编辑 - 但它会以不是只是;;;;;的行为例。

所以要避免这些:

perl -i.bak -ne 'if (m/;;;;/) { print join ( q{\N}, split // ) } else { print }'

或许更简洁:

perl -i.bak -pe '$_ = join ( q{\N}, split // ) if m/;;;/'

答案 1 :(得分:3)

由于您无法匹配相同字符的两倍,因此您的方法不起作用。要解决此问题,您只能检查是否存在以下情况;前瞻(第二个;不是比赛的一部分):

s/;(?=;)/;\\N/g