2015-03-26 2 views
0

У меня есть скрипт Perl, который должен иметь возможность заменять значения, содержащиеся в тегах CDATA в XML. У меня есть следующий вопрос:Perl регулярное выражение для замены точного числа в строке 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" (не желательно).

Любая помощь была бы принята с благодарностью! Спасибо ...

+1

Вот почему у нас есть XML-парсеры. –

+0

Согласен ... но не может использовать. – sconicelli

+0

Я также должен добавить, что даже если бы я мог разобрать этот XML с любым XML-модулем, то такая же работа должна выполняться в строке ... так же проблема связана с XML или плоским файлом без CDATA. – sconicelli

ответ

2

Если вы хотите заменить только целые слова, используйте словоразделы \b:

s/\b00\b/10/; 

Или, если вы хотите заменить только тогда, когда никакие цифры не предшествуют или не следуют за строкой, используйте утверждения обхода:

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

Это сделал это ... Я использовал следующее: если ($ s_param = ~/\ D /) \t \t { \t \t $ _ = ~ s/\ Ь $ s_param \ б/$ t_param/г, если $ _ = ~ m/ sconicelli

0

Использование словоразделы:

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

Этот ответ появился в очереди низкого качества, по-видимому, потому, что вы не объяснили код. Если вы объясните это (в своем ответе), у вас гораздо больше шансов получить больше бонусов - и у испытуемого больше шансов узнать что-то! –

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; 
} 
Смежные вопросы