Perl: правильно цитируя все специальные символы

У меня есть образец строки, содержащий 2 обратных слеша. Пожалуйста, не спрашивайте меня об источнике строки, это просто пример строки.

my $string = "use Ppppp\\Ppppp;";
print $string;

Оба, двойные кавычки или кавычки будут печатать

use Ppppp\Ppppp;

С помощью

my $string = "\Quse Ppppp\\Ppppp;\E";
print $string;

распечатает

use\ Ppppp\\Ppppp\;

добавив эти дополнительные обратные слеши к выходу.

Есть ли в Perl простое решение для отображения строки "буквально", без изменения строки, например, добавление дополнительных обратных косых черт для выхода?

1 ответ

У меня есть образец строки, содержащий 2 обратных слеша....

my $string = "use Ppppp\\Ppppp;";

Извините, но вы ошибаетесь - эта строка содержит только одну обратную косую черту *, так как \\ является escape-последовательностью в строках с двойными кавычками (и одинарными кавычками), которые производят один обратный слеш. Смотрите также "Операторы цитирования и подобные им" в perlop. Если ваша строка действительно содержит две обратные косые черты, то вам нужно написать "use Ppppp\\\\Ppppp;" или используйте heredoc, как в:

chomp( my $string = <<'ENDSTR' );
use Ppppp\\Ppppp;
ENDSTR

Если вы хотите, чтобы вывод строки представлял собой действительный исходный код Perl (используя его экранирование), вы можете использовать один из нескольких вариантов:

my $string = "use Ppppp\\Ppppp;";
# option 1
use Data::Dumper;
$Data::Dumper::Useqq=1;
$Data::Dumper::Terse=1;
print Dumper($string);
# option 2
use Data::Dump;
dd $string;
# option 3
use B;
print B::perlstring($string);

Каждый из них напечатает "use Ppppp\\Ppppp;", (Конечно, есть и другие модули. Лично мне нравится Data::Dump, Data::Dumper основной модуль.)

Использование одного из этих модулей также является лучшим способом проверить $string переменная действительно содержит.

Если это по-прежнему не соответствует вашим потребностям: в предыдущей редакции вашего вопроса было сказано: "Как правильно экранировать все специальные символы, включая обратную косую черту?" - вам нужно будет указать полный список символов, которые вы считаете особенными. Вы можете сделать что-то вроде этого, например:

use 5.014; # for s///r
my $string = "use Ppppp\\Ppppp;";
print $string=~s/(?=[\\])/\\/gr;

Это будет печатать $string с двойной косой чертой, без изменения $string, Вы также можете добавить больше символов в класс символов регулярных выражений, чтобы добавить обратную косую черту перед этими символами.

* Обновление: так что я не слишком педантичен: конечно, исходный код Perl содержит две обратные косые черты. Но есть разница между литеральным исходным кодом и тем, что содержит строка Perl, так же, как строка "Foo\nBar" содержит символ новой строки вместо двух буквенных символов \ а также n,

Ради полноты, как уже обсуждалось в комментариях: \Q\E (ака quotemeta) в первую очередь предназначен для экранирования любых специальных символов, которые могут быть специальными для регулярных выражений (все символы ASCII не совпадают) /[A-Za-z_0-9]/), поэтому он также избегает пробелов и точек с запятой.

Поскольку вы упоминаете внешние файлы: Если вы читаете строку, такую ​​как use Ppppp\\Ppppp; из внешнего файла, то строка Perl будет содержать две обратные косые черты, и если вы print это, это также покажет две обратные косые черты. Но если вы хотите представить эту строку как исходный код Perl, вы должны написать "use Ppppp\\\\Ppppp;" (или используйте один из других методов из вопроса, на который вы ссылались).

Другие вопросы по тегам