Perl 正则表达式替换 CDATA 字符串中的确切数字

Perl regular expression to replace exact number within CDATA string

我有一个 Perl 脚本,需要能够替换 XML 中 CDATA 标签中包含的值。我有以下问题:

my $str = "<![CDATA[Replace 00 and 00 but don't replace 1001100.]]>";
my $source = "00";
my $target = "989898";

$str =~ s/(<!\[(?i)CDATA(?-i)\[.*)$source(.*\].*)/$target/g;

我正在寻找的输出是:

<![CDATA[Replace 989898 and 989898 but don't replace 1001100.]]>

我得到的是:

<![CDATA[Replace 00 and 00 but do not replace 10011989898.]]>

如果 $str 等于以下内容,我还需要能够替换 $source

$str = "<![CDATA[HEREISSOMETEXT00]]>";

期望的输出是:

<![CDATA[HEREISSOMETEXT989898]]>

我还需要对路径进行如下更改:

my $str = "<![CDATA[/this/is/my/CHANGE_ME/path]]>";
my $source = "CHANGE_ME";
my $target = "NEW_ME";

期望的输出是:

<![CDATA[/this/is/my/NEW_ME/path]]>

而且还需要以下功能:

my $str = "<![CDATA[/this/is/my/DONOTCHANGE_ME/path]]>";
my $source = "CHANGE_ME";
my $target = "NEW_ME";

期望的输出:

<![CDATA[/this/is/my/DONOTCHANGE_ME/path]]>

基本上,我需要子字符串内的精确匹配,我不能使用任何未随 Perl 提供的 Perl 库 "out of the box."

我也写了这个更简单的正则表达式:

$str =~ s/$source/$target/g if $_ =~ m/<!\[CDATA/i;

每当我只需要替换 "ABC" 甚至 "AB0" 之类的字符串时,这都很好用,但是如果我需要将 "00" 更改为 "10",这会造成严重破坏,因为它将 "00" 替换为 "10"(需要),将 "1000" 替换为 "1100"(不需要)。

如有任何帮助,我们将不胜感激!谢谢...

使用单词边界:

my $source = qr"\b00\b";

如果只想替换整个单词,请使用单词边界 \b:

s/\b00\b/10/;

或者,如果您只想在字符串前后没有数字时进行替换,请使用环视断言:

s/ (?<![0-9]) 00 (?![0-9]) /10/x;

以下正是我所需要的:

if ($s_param =~ /\D/)
#I'm a word
{
  $_ =~ s/\b$s_param\b/$t_param/g if $_ =~ m/<!\[CDATA/i;
}
else
#I'm a number
{
  $_ =~ s/(?<![0-9])$s_param(?![0-9])/$t_param/g if $_ =~ m/<!\[CDATA/i;
}