我想在perl脚本中的给定字符串(包括转义字符)中替换一个子字符串(包括转义字符)。如果可能的话用regexp。
输入:
abcdefg hijkl: (mnop-qrst) uvwx
aabbccd deeff: (gghh-iijj) kkll
aaabbbc ccddd: (eeef-ffgg) ghhh
替换字符串示例:
ijkl:
gghh-iijj
ccddd: (eeef-ffgg)
输出:
abcdefg hXXXX: (mnop-qrst) uvwx
aabbccd deeff: (XXXX-XXXX) kkll
aaabbbc XXXXX: (XXXX-XXXX) ghhh
除了一篇文章“有办法用长度相同的X字符替换子字符串吗?”,我什么也没找到,但是没有转义字符。
regexp $s =~ s/(\Q$pattern\E)/'X' x length $1/e;
适用于任何字母数字替换字符串,但如果它包含像()=,.-:;*
这样的特殊字符,则不适用。
在上面的例子中,输入和替换字符串都可以包含特殊字符。
发布于 2015-06-26 03:48:58
更新
这里有一个解决方案,允许模式中的任何空格与目标字符串中的任意数量的空格匹配。注意,要做到这一点,我必须手动转义非单词字符,因此不再需要\Q
.\E
请注意,最后一个模式在ccddd:
和(eeef-ffgg)
之间有许多空格,但它正确地匹配字符串中的单个空格。
use strict;
use warnings;
my @patterns = (
'ijkl:',
'gghh-iijj',
'ccddd: (eeef-ffgg)',
);
# Build and compile the regex
my $pattern = join '|', map {
my $item = $_;
$item =~ s/([^\w\s])/\\$1/g;
$item =~ s/\s+/\\s+/g;
$item;
} @patterns;
$pattern = qr/$pattern/;
while ( my $s = <DATA> ) {
$s =~ s/($pattern)/$1 =~ tr{a-zA-Z0-9}{X}r/eg;
print $s;
}
__DATA__
abcdefg hijkl: (mnop-qrst) uvwx
aabbccd deeff: (gghh-iijj) kkll
aaabbbc ccddd: (eeef-ffgg) ghhh
输出
abcdefg hXXXX: (mnop-qrst) uvwx
aabbccd deeff: (XXXX-XXXX) kkll
aaabbbc XXXXX: (XXXX-XXXX) ghhh
原始员额
所需要的就是替换
s/(\Q$pattern\E)/'X' x length $1/e
使用
s/(\Q$pattern\E)/$1 =~ tr{a-zA-Z0-9}{X}r/e
这里有个示范。请注意,/r
修饰符需要perlv5.14或更高版本
use strict;
use warnings;
use 5.014;
my @matches = (
'ijkl:',
'gghh-iijj',
'ccddd: (eeef-ffgg)',
);
while ( my $s = <DATA> ) {
$s =~ s/(\Q$_\E)/$1 =~ tr{a-zA-Z0-9}{X}r/e for @matches;
print $s;
}
__DATA__
abcdefg hijkl: (mnop-qrst) uvwx
aabbccd deeff: (gghh-iijj) kkll
aaabbbc ccddd: (eeef-ffgg) ghhh
输出
abcdefg hXXXX: (mnop-qrst) uvwx
aabbccd deeff: (XXXX-XXXX) kkll
aaabbbc XXXXX: (XXXX-XXXX) ghhh
发布于 2015-06-26 00:50:37
这里我建议的诀窍是,预先生成正则表达式。
use strict;
use warnings;
my @replace_strings = qw ( ijkl:
mnop-qrst
hijkl: );
my %replace = map { $_ => "X" x length($_) } @replace_strings;
my $replace_regex = join( "|", map {quotemeta} @replace_strings );
$replace_regex = qr/($replace_regex)/;
while (<DATA>) {
s/$replace_regex/$replace{$1}/g;
print;
}
__DATA__
abcdefg hijkl: (mnop-qrst) uvwx
我们:
因此,这印出:
abcdefg XXXXXX (XXXXXXXXX) uvwx
你可以用类似的技术。
后面是注释--看起来您想要定义一些字符串,只需替换它们中的文本。
那么像这样的事情怎么样:
my %replace = map { $_ => ($_ =~ s/\w/X/gr) } @replace_strings;
它(根据您的源数据)提供:
abcdefg hXXXX: (mnop-qrst) uvwx
aabbccd deeff: (XXXX-XXXX) kkll
aaabbbc XXXXX: (XXXX-XXXX) ghhh
(如果您也想替换它,可以将-
添加到模式中)。
https://stackoverflow.com/questions/31068009
复制相似问题