仅替换 Perl 模式的匹配部分
Substitute only in the matched part of a Perl pattern
如何仅替换匹配的模式并使用 Perl 将其放回同一个变量中?
例如:
my $str = "a.b.AA pat1 BB hgf AA pat1 BB jkl CC pat1 don't change pat1";
我想在 AA
和 BB
之间匹配 pat1
并将其替换为原始字符串 PAT2。但是,我不想在同一字符串中的其他任何地方替换 pat1
预期输出字符串:
a.b.AA PAT2 BB hgf AA PAT2 BB jkl CC pat1 don't change pat1
我相信应该有一些好的方法来做到这一点;请指教
原始字符串:
my $ORG_str = 'A.B.C.\valid.A .\valid.A.B.C .\valid.X.Y.Z .p.q.r.s';
预期字符串:
my $EXP_op = 'A.B.C.\valid?A .\valid?A?B?C .\valid?X?Y?Z .p.q.r.s';
仅当字符 .
位于反斜杠 \
和空格 </code>.</p> 之间时,才将字符 <code>.
替换为 ?
s/(?<=AA )pat1(?= BB)/pat2/g
这匹配并替换被 AA
和 BB
包围的 pat1
。
\\[^. ]*\K|(?!^)\G\.([^. ]*)
您可以通过 ?
尝试 this.Replace。查看演示。
https://regex101.com/r/mT0iE7/28
生成的字符串不会与您想要的完全相同,但您可以轻松地进行清理。
\?(?=\?)
替换为 empty string
,您就得到了 want.See 演示。
一个正则表达式不是很简单,所以我使用分而治之的方法来计算结果。这是一个小的递归函数,用于替换单个“.”。每组 ('\' ' ')
当没有可替换的东西时迭代结束
sub replace {
my ($input) = @_;
my $result = $input;
$result =~ s/(\\S*?)\.(.*? )/?/g;
return $result if $result eq $input;
return replace($result);
}
带有一些测试用例的函数
use strict;
my $ORG_str= 'A.B.C.\\valid.A .\\valid.A.B.C .\\valid.X.Y.Z .p.q.r.s';
my $EXP_op ='A.B.C.\\valid?A .\\valid?A?B?C .\\valid?X?Y?Z .p.q.r.s';
sub replace {
my ($input) = @_;
my $result = $input;
$result =~ s/(\\S*?)\.(.*? )/?/g;
return $result if $result eq $input;
return replace($result);
}
my $check;
my $result;
my $expected;
$check = 'abcd'; $expected = $check;
$result = replace($check);
assert($result eq $expected, "'$check' gives '$expected'");
$check = 'ab\xxx. cd'; $expected = 'ab\xxx? cd';
$result = replace($check);
assert($result eq $expected, "'$check' gives '$expected'");
$check = 'ab\x.x.x. cd'; $expected = 'ab\x?x?x? cd';
$result = replace($check);
assert($result eq $expected, "'$check' gives '$expected'");
$check = 'ab\x.x.x. cd\y.y.y.'; $expected = 'ab\x?x?x? cd\y.y.y.';
$result = replace($check);
assert($result eq $expected, "'$check' gives '$expected'");
$check = 'ab\x.x.x. cd\xxx.xxx..xxx...x \y.y.y.'; $expected = 'ab\x?x?x? cd\xxx?xxx??xxx???x \y.y.y.';
$result = replace($check);
assert($result eq $expected, "'$check' gives '$expected'");
$check = '. ..\.. ...\.. ...\.. ...\..'; $expected = '. ..\?? ...\?? ...\?? ...\..';
$result = replace($check);
assert($result eq $expected, "'$check' gives '$expected'");
$check = $ORG_str; $expected = $EXP_op;
$result = replace($check);
assert($result eq $expected, "'$check' gives '$expected'");
sub assert {
my ($cond, $mesg) = @_;
print "checking $mesg ... ";
die "\nFAIL: $mesg" unless $cond;
print "OK\n";
}
结果
checking 'abcd' gives 'abcd' ... OK
checking 'ab\xxx. cd' gives 'ab\xxx? cd' ... OK
checking 'ab\x.x.x. cd' gives 'ab\x?x?x? cd' ... OK
checking 'ab\x.x.x. cd\y.y.y.' gives 'ab\x?x?x? cd\y.y.y.' ... OK
checking 'ab\x.x.x. cd\xxx.xxx..xxx...x \y.y.y.' gives 'ab\x?x?x? cd\xxx?xxx??xxx???x \y.y.y.' ... OK
checking '. ..\.. ...\.. ...\.. ...\..' gives '. ..\?? ...\?? ...\?? ...\..' ... OK
checking 'A.B.C.\valid.A .\valid.A.B.C .\valid.X.Y.Z .p.q.r.s' gives 'A.B.C.\valid?A .\valid?A?B?C .\valid?X?Y?Z .p.q.r.s' ... OK
如何仅替换匹配的模式并使用 Perl 将其放回同一个变量中?
例如:
my $str = "a.b.AA pat1 BB hgf AA pat1 BB jkl CC pat1 don't change pat1";
我想在 AA
和 BB
之间匹配 pat1
并将其替换为原始字符串 PAT2。但是,我不想在同一字符串中的其他任何地方替换 pat1
预期输出字符串:
a.b.AA PAT2 BB hgf AA PAT2 BB jkl CC pat1 don't change pat1
我相信应该有一些好的方法来做到这一点;请指教
原始字符串:
my $ORG_str = 'A.B.C.\valid.A .\valid.A.B.C .\valid.X.Y.Z .p.q.r.s';
预期字符串:
my $EXP_op = 'A.B.C.\valid?A .\valid?A?B?C .\valid?X?Y?Z .p.q.r.s';
仅当字符 .
位于反斜杠 \
和空格 </code>.</p> 之间时,才将字符 <code>.
替换为 ?
s/(?<=AA )pat1(?= BB)/pat2/g
这匹配并替换被 AA
和 BB
包围的 pat1
。
\\[^. ]*\K|(?!^)\G\.([^. ]*)
您可以通过 ?
尝试 this.Replace。查看演示。
https://regex101.com/r/mT0iE7/28
生成的字符串不会与您想要的完全相同,但您可以轻松地进行清理。
\?(?=\?)
替换为 empty string
,您就得到了 want.See 演示。
一个正则表达式不是很简单,所以我使用分而治之的方法来计算结果。这是一个小的递归函数,用于替换单个“.”。每组 ('\' ' ')
当没有可替换的东西时迭代结束
sub replace {
my ($input) = @_;
my $result = $input;
$result =~ s/(\\S*?)\.(.*? )/?/g;
return $result if $result eq $input;
return replace($result);
}
带有一些测试用例的函数
use strict;
my $ORG_str= 'A.B.C.\\valid.A .\\valid.A.B.C .\\valid.X.Y.Z .p.q.r.s';
my $EXP_op ='A.B.C.\\valid?A .\\valid?A?B?C .\\valid?X?Y?Z .p.q.r.s';
sub replace {
my ($input) = @_;
my $result = $input;
$result =~ s/(\\S*?)\.(.*? )/?/g;
return $result if $result eq $input;
return replace($result);
}
my $check;
my $result;
my $expected;
$check = 'abcd'; $expected = $check;
$result = replace($check);
assert($result eq $expected, "'$check' gives '$expected'");
$check = 'ab\xxx. cd'; $expected = 'ab\xxx? cd';
$result = replace($check);
assert($result eq $expected, "'$check' gives '$expected'");
$check = 'ab\x.x.x. cd'; $expected = 'ab\x?x?x? cd';
$result = replace($check);
assert($result eq $expected, "'$check' gives '$expected'");
$check = 'ab\x.x.x. cd\y.y.y.'; $expected = 'ab\x?x?x? cd\y.y.y.';
$result = replace($check);
assert($result eq $expected, "'$check' gives '$expected'");
$check = 'ab\x.x.x. cd\xxx.xxx..xxx...x \y.y.y.'; $expected = 'ab\x?x?x? cd\xxx?xxx??xxx???x \y.y.y.';
$result = replace($check);
assert($result eq $expected, "'$check' gives '$expected'");
$check = '. ..\.. ...\.. ...\.. ...\..'; $expected = '. ..\?? ...\?? ...\?? ...\..';
$result = replace($check);
assert($result eq $expected, "'$check' gives '$expected'");
$check = $ORG_str; $expected = $EXP_op;
$result = replace($check);
assert($result eq $expected, "'$check' gives '$expected'");
sub assert {
my ($cond, $mesg) = @_;
print "checking $mesg ... ";
die "\nFAIL: $mesg" unless $cond;
print "OK\n";
}
结果
checking 'abcd' gives 'abcd' ... OK
checking 'ab\xxx. cd' gives 'ab\xxx? cd' ... OK
checking 'ab\x.x.x. cd' gives 'ab\x?x?x? cd' ... OK
checking 'ab\x.x.x. cd\y.y.y.' gives 'ab\x?x?x? cd\y.y.y.' ... OK
checking 'ab\x.x.x. cd\xxx.xxx..xxx...x \y.y.y.' gives 'ab\x?x?x? cd\xxx?xxx??xxx???x \y.y.y.' ... OK
checking '. ..\.. ...\.. ...\.. ...\..' gives '. ..\?? ...\?? ...\?? ...\..' ... OK
checking 'A.B.C.\valid.A .\valid.A.B.C .\valid.X.Y.Z .p.q.r.s' gives 'A.B.C.\valid?A .\valid?A?B?C .\valid?X?Y?Z .p.q.r.s' ... OK