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

时间:2015-03-26 18:28:22

标签: regex perl cdata

我有一个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(.*\].*)/$1$target$2/g;

我正在寻找的输出是:

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

我得到的是:

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

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

$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库“开箱即用”。

我也写过这么简单的正则表达式:

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

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

任何帮助将不胜感激!感谢...

3 个答案:

答案 0 :(得分:2)

如果您只想替换整个单词,请使用单词boundary \b

s/\b00\b/10/;

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

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

答案 1 :(得分:0)

使用字边界:

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

答案 2 :(得分:0)

以下内容让我知道我需要的内容:

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;
}