如何用字符'X'替换子串中的字符,包括转义字符?
How to replace the characters in substring, including escape characters, with the character 'X'?
我想替换 perl 脚本中给定字符串(包括转义字符)内的子字符串(包括转义字符)。如果可能,使用正则表达式。
输入:
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
除了文章"Is there a way to replace a substring with a same amount of X characters the length of it?",我没有找到任何内容,但是没有转义字符。
正则表达式 $s =~ s/(\Q$pattern\E)/'X' x length /e;
适用于任何字母数字替换字符串,但如果它包含 ()=,.-:;*
等特殊字符则无效
在上面的示例中,输入字符串和替换字符串都可以包含特殊字符。
我建议的技巧是预先生成您的正则表达式模式。
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{}/g;
print;
}
__DATA__
abcdefg hijkl: (mnop-qrst) uvwx
我们:
- 使用 'replacement strings' 的列表。
- 使用映射生成替换(X x 长度)
- 生成正则表达式以匹配 'search'
- 然后用它来应用 'replace'
因此打印:
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
(如果您也想替换它,可以将 -
添加到模式中)。
更新
这是一个解决方案,允许模式中的任何白色space 匹配目标字符串中任意数量的白色space。请注意,为此,我必须手动转义非单词字符,因此不再需要 \Q
...\E
请注意,最后一个模式在 ccddd:
和 (eeef-ffgg)
之间有许多 space,但它正确匹配字符串
中的单个 space
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])/\/g;
$item =~ s/\s+/\s+/g;
$item;
} @patterns;
$pattern = qr/$pattern/;
while ( my $s = <DATA> ) {
$s =~ s/($pattern)/ =~ 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
原版post
只需更换
s/(\Q$pattern\E)/'X' x length /e
和
s/(\Q$pattern\E)/ =~ tr{a-zA-Z0-9}{X}r/e
这是一个演示。请注意,/r
修饰符需要 Perl v5.14 或更高版本
use strict;
use warnings;
use 5.014;
my @matches = (
'ijkl:',
'gghh-iijj',
'ccddd: (eeef-ffgg)',
);
while ( my $s = <DATA> ) {
$s =~ s/(\Q$_\E)/ =~ 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
我想替换 perl 脚本中给定字符串(包括转义字符)内的子字符串(包括转义字符)。如果可能,使用正则表达式。
输入:
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
除了文章"Is there a way to replace a substring with a same amount of X characters the length of it?",我没有找到任何内容,但是没有转义字符。
正则表达式 $s =~ s/(\Q$pattern\E)/'X' x length /e;
适用于任何字母数字替换字符串,但如果它包含 ()=,.-:;*
在上面的示例中,输入字符串和替换字符串都可以包含特殊字符。
我建议的技巧是预先生成您的正则表达式模式。
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{}/g;
print;
}
__DATA__
abcdefg hijkl: (mnop-qrst) uvwx
我们:
- 使用 'replacement strings' 的列表。
- 使用映射生成替换(X x 长度)
- 生成正则表达式以匹配 'search'
- 然后用它来应用 'replace'
因此打印:
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
(如果您也想替换它,可以将 -
添加到模式中)。
更新
这是一个解决方案,允许模式中的任何白色space 匹配目标字符串中任意数量的白色space。请注意,为此,我必须手动转义非单词字符,因此不再需要 \Q
...\E
请注意,最后一个模式在 ccddd:
和 (eeef-ffgg)
之间有许多 space,但它正确匹配字符串
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])/\/g;
$item =~ s/\s+/\s+/g;
$item;
} @patterns;
$pattern = qr/$pattern/;
while ( my $s = <DATA> ) {
$s =~ s/($pattern)/ =~ 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
原版post
只需更换
s/(\Q$pattern\E)/'X' x length /e
和
s/(\Q$pattern\E)/ =~ tr{a-zA-Z0-9}{X}r/e
这是一个演示。请注意,/r
修饰符需要 Perl v5.14 或更高版本
use strict;
use warnings;
use 5.014;
my @matches = (
'ijkl:',
'gghh-iijj',
'ccddd: (eeef-ffgg)',
);
while ( my $s = <DATA> ) {
$s =~ s/(\Q$_\E)/ =~ 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