Perl: как заменить расширенные символы соответствующей им сущностью в XML-файле?

#perl

#perl

Вопрос:

В XML-файле мне нужно преобразовать все символы выше символьного кода 127 в соответствующую им буквенную сущность (обычно преобразовать é в amp;#xe9; ).

Вот что я написал, но это не работает.

 sub as_entity{
  my $char = shift;
  return sprintf("amp;#x%.4x;", ord($char));
}

sub entitify{
  my $str = shift;
  $str =~ s/([x7f-x{ffffff}])/(?{as_entity($1)})/g;
  return $str;
}
  

Кажется, я не могу использовать (?{...}) в заменяющей части…

Какой был бы наилучший способ добиться этого?

Комментарии:

1. (?{...}) это атом регулярного выражения. Его нельзя использовать вне шаблонов регулярных выражений

Ответ №1:

 $str =~ s/([x7f-x{ffffff}])/as_entity($1)/ge;
  

должно быть достаточно. (Обратите внимание на дополнительный /e модификатор.)

Комментарии:

1. Должно быть x80 , а не x7F соответствовать спецификации операционной системы. Я бы написал это как [^x00-x7F]

2. @ikegami: Я не касался этой части регулярного выражения, и я считаю, что x7f «правильно» — это символ DEL, который, вероятно, следует экранировать.

3. @ikegami : вы правы, хотя символ удаления (charcode 127) также экранирован, мое описание было не совсем точным в этом отношении. В любом случае спасибо за упоминание.

4. @subtenante, по этой логике, 00-1F, кроме 09, 0A и 0D, также должны быть экранированы.