朋友们,
在替换正则表达式方面需要一些帮助。我有一个字符串
;;;;;;;;;;;;;
我需要用
;\N;\N;\N;\N;\N;\N;\N;\N;\N;\N;\N;\N;
我试过
s/;;/;\\N/;/g
但它给了我
;\N;;\N;;\N;;\N;;\N;;\N;;
试图摆弄前瞻和后视,但无法解决。
朋友们,
在替换正则表达式方面需要一些帮助。我有一个字符串
;;;;;;;;;;;;;
我需要用
;\N;\N;\N;\N;\N;\N;\N;\N;\N;\N;\N;\N;
我试过
s/;;/;\\N/;/g
但它给了我
;\N;;\N;;\N;;\N;;\N;;\N;;
试图摆弄前瞻和后视,但无法解决。
我不会为此使用正则表达式,而是使用split
:
#!/usr/bin/env perl
use strict;
use warnings;
my $str = ';;;;;;;;;;;;;';
print join ( '\N', split ( //, $str ) );
拆分空值,获取每个字符,并利用 join 在字符之间放置分隔符的事实。(所以不是在第一个之前,也不是在最后一个之后)。
这给出了:
;\N;\N;\N;\N;\N;\N;\N;\N;\N;\N;\N;\N;
我认为哪个符合您想要的输出?
作为一个单行者,这将是:
perl -ne 'print join ( q{\N}, split // )'
注意 - 我们需要单引号'
而不是双引号,\N
所以它不会被插值。
如果您需要处理可变内容(例如,不仅仅是;
),您可以添加grep
或map
混合 - 我需要一些示例数据来为您提供有用的答案。
我用它来编辑文件,正则表达式更适合我
从那以后 -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 $_;
}
例如,它实际上在做的是:
并且随着-i
该打印被重定向到新的文件名。
您不必限制自己-p
- 任何生成输出的东西都将以这种方式工作 - 尽管请记住,如果它不“通过”任何它不修改的行(就像正则表达式转换一样)它会丢失数据。
但你绝对可以这样做:
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/;;;/'
由于您无法匹配两次相同的字符,因此您的方法不起作用。要解决该问题,您只能检查以下是否存在;具有前瞻性(第二个 ; 不是比赛的一部分):
s/;(?=;)/;\\N/g