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;
}
我有一个 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;
}