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;"
(или используйте один из других методов из вопроса, на который вы ссылались).