Perl 正则表达式替换 - 多个匹配项
Perl regexp substitution - multiple matches
朋友,
需要一些替换正则表达式方面的帮助。
我有一个字符串
;;;;;;;;;;;;;
我需要将其替换为
;\N;\N;\N;\N;\N;\N;\N;\N;\N;\N;\N;\N;
我试过了
s/;;/;\N/;/g
但它给了我
;\N;;\N;;\N;;\N;;\N;;\N;;
尝试fiddle前瞻和后视,但无法解决。
因为您不能匹配两次相同的字符,所以您的方法是行不通的。要解决问题,您只能检查是否存在以下内容;向前看(第二个 ; 不是比赛的一部分):
s/;(?=;)/;\N/g
我不会为此使用正则表达式,而是使用 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;
我认为哪个符合您想要的输出?
作为单行者,这将是:
perl -ne 'print join ( q{\N}, split // )'
注意 - 我们需要单引号 '
而不是双引号 \N
这样它就不会被插入。
如果您需要处理可变内容(例如,不仅仅是 ;
),您可以将 grep
或 map
添加到组合中 - 我需要一些示例数据来为您提供不过那里有一个有用的答案。
I use this for infile edit, the regexp suits me better
从那开始 - 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
- 任何生成输出的内容都将以这种方式工作 - 但请记住,如果它没有 'pass through' 它没有的任何行'修改(作为正则表达式转换)它会丢失数据。
但你绝对可以做到:
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/;;;/'
朋友,
需要一些替换正则表达式方面的帮助。 我有一个字符串
;;;;;;;;;;;;;
我需要将其替换为
;\N;\N;\N;\N;\N;\N;\N;\N;\N;\N;\N;\N;
我试过了
s/;;/;\N/;/g
但它给了我
;\N;;\N;;\N;;\N;;\N;;\N;;
尝试fiddle前瞻和后视,但无法解决。
因为您不能匹配两次相同的字符,所以您的方法是行不通的。要解决问题,您只能检查是否存在以下内容;向前看(第二个 ; 不是比赛的一部分):
s/;(?=;)/;\N/g
我不会为此使用正则表达式,而是使用 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;
我认为哪个符合您想要的输出?
作为单行者,这将是:
perl -ne 'print join ( q{\N}, split // )'
注意 - 我们需要单引号 '
而不是双引号 \N
这样它就不会被插入。
如果您需要处理可变内容(例如,不仅仅是 ;
),您可以将 grep
或 map
添加到组合中 - 我需要一些示例数据来为您提供不过那里有一个有用的答案。
I use this for infile edit, the regexp suits me better
从那开始 - 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
- 任何生成输出的内容都将以这种方式工作 - 但请记住,如果它没有 'pass through' 它没有的任何行'修改(作为正则表达式转换)它会丢失数据。
但你绝对可以做到:
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/;;;/'