我想在字符串中用子串“[ids]”,“[order]”和“[limit]”替换三个其他子串(作为参数传递给我的例程)。
但是如果“[”或“]”前面加上“\”(“\ [”,“\]”),我想取消“[...]”的特殊含义。 “\”也应自行取消:“\\”表示“\”。
如何在Perl中实现它?
请注意,我们可能会使用其他内容而不是“[ids]”,“[order]”和“[limit]”。这不是一成不变的。
答案 0 :(得分:2)
为什么不使用现有的模板module而不是发明另一个模板?
无论如何,这是一个处理你的格式的解析器。
my %replace = (
ids => ...,
...
);
my $out = '';
for ($in) {
if (/\G ( (?: [^\\\[\]]+ | \\. )+ ) /xsgc) {
$out .= $1;
redo;
}
if (/\G \[ ( (?: [^\\\[\]]+ | \\. )+ ) \] /xsgc) {
die if !exists($replace{$1});
$out .= $replace{$1};
redo;
}
die if !/\G\Z/xsgc;
}
答案 1 :(得分:0)
#!/usr/bin/perl
use strict;
use warnings;
sub replace_squared_terms {
my ($str, $hash) = @_;
my $new = "";
for(;;) {
return $new if $str eq "";
if($str =~ /^([^\[\]\\\/]+)(.*)/s) {
$new .= $1;
$str = $2;
} elsif($str =~ /^\[([^\/\[\]]+)\](.*)/s) {
die "Wrong template" unless exists $hash->{$1};
$new .= $hash->{$1};
$str = $2;
} elsif($str =~ /^\\(.)(.*)/s) {
$new .= $1;
$str = $2;
} else {
die "Wrong template";
}
}
}
my $str = "[a] [b] \\[ [a] \\\\";
print replace_squared_terms($str, {a=>"123", b=>"XYZ"}), "\n";
答案 2 :(得分:0)
这是你可以做到的一种方式:
sub replace{
my ($str, $ids, $order, $limit) = @_;
$str =~ s/(?<!\\)((?:\\.)*) \[ (?: (ids) | (order) | limit ) \]/
$1 . ($2? $ids: $3? $order: $limit)/gsex;
return $str;
}
示例:
print replace <<'_STR_', '<1DZ>', '<0RD3RZ>', '<L1M1TZ>';
[ids][order][limit]
\[ids]\\[ids]\\\[ids]
_STR_
输出:
<1DZ><0RD3RZ><L1M1TZ>
\[ids]\\<1DZ>\\\[ids]