Синдром наклоненной зубочистки
В компьютерном программировании синдром наклоненной зубочистки ( LTS ) — это ситуация, в которой выражение в кавычках становится нечитаемым, поскольку оно содержит большое количество escape-символов , обычно обратных косых черт ("\"), чтобы избежать столкновения разделителей . [1] [2]
Официальная Perl документация [3] ввел этот термин в более широкое использование; там эта фраза используется для описания регулярных выражений , соответствующих путям в стиле Unix , в которых элементы разделены косой чертой. /
. Косая черта также используется в качестве разделителя регулярных выражений по умолчанию, поэтому, чтобы ее можно было использовать в выражении буквально, ее необходимо экранировать обратной косой чертой. \
, что приводит к частым экранированным косым чертам, представленным как \/
. Если удвоить, как в URL-адресах, это даст \/\/
для сбежавшего //
. Аналогичное явление происходит для DOS / Windows путей , где в качестве разделителя пути используется обратная косая черта, требующая двойной обратной косой черты. \\
– затем это можно повторно экранировать для регулярного выражения внутри экранированной строки, требуя \\\\
для соответствия одной обратной косой черте. В крайних случаях, например, регулярное выражение в экранированной строке, соответствующее пути Единого соглашения об именах (который начинается \\
) требуется 8 обратных косых черт \\\\\\\\
из-за двух обратных косых черт, каждая из которых имеет двойное экранирование.
LTS появляется во многих языках программирования и во многих ситуациях, в том числе в шаблонах, соответствующих унифицированным идентификаторам ресурсов (URI), и в программах, выводящих текст в кавычках. Многие куайны попадают в последнюю категорию.
Пример шаблона
[ редактировать ]Рассмотрим следующее регулярное выражение Perl, предназначенное для сопоставления URI, которые идентифицируют файлы под именем pub
каталог FTP- сайта:
m/ftp:\/\/[^\/]*\/pub\//
Perl, как и до него sed , решает эту проблему, позволяя использовать множество других символов в качестве разделителей регулярного выражения. Например, следующие три примера эквивалентны приведенному выше выражению:
m{ftp://[^/]*/pub/} m#ftp://[^/]*/pub/# m!ftp://[^/]*/pub/!
Или этот общий перевод для преобразования обратной косой черты в косую черту:
tr/\\/\//
может быть легче понять, если написать так:
tr{\\}{/}
Пример цитируемого текста
[ редактировать ]Программа Perl для печати тега ссылки HTML, где URL-адрес и текст ссылки хранятся в переменных. $url
и $text
соответственно, может выглядеть так. Обратите внимание на использование обратной косой черты для экранирования символов в двойных кавычках:
print "<a href=\"$url\">$text</a>";
Использование одинарных кавычек для разделения строки невозможно, поскольку Perl не расширяет переменные внутри строк, заключенных в одинарные кавычки. Например, приведенный ниже код не будет работать должным образом:
print '<a href="$url">$text</a>'
Используя printf
функция является жизнеспособным решением на многих языках (Perl, C , PHP ):
printf('<a href="%s">%s</a>', $url, $text);
The qq
Оператор в Perl допускает любой разделитель:
print qq{<a href="$url">$text</a>};
print qq|<a href="$url">$text</a>|;
print qq(<a href="$url">$text</a>);
Здесь документы особенно хорошо подходят для многострочных строк; однако в документах Perl до версии 5.26 не допускались правильные отступы . [4] В этом примере показан синтаксис Perl:
print <<HERE_IT_ENDS;
<a href="$url">$text</a>
HERE_IT_ENDS
Другие языки
[ редактировать ]С#
[ редактировать ]Язык программирования C# обрабатывает LTS с помощью @
символ в начале строковых литералов, перед начальными кавычками, например
string filePath = @"C:\Foo\Bar.txt";
вместо того, чтобы требовать иного:
string filePath = "C:\\Foo\\Bar.txt";
С++
[ редактировать ]Стандарт C++11 добавляет необработанные строки :
std::string filePath = R"(C:\Foo\Bar.txt)";
Если строка содержит символы )"
, можно использовать необязательный разделитель, например d
в следующем примере:
std::regex re{ R"d(s/"\([^"]*\)"/'\1'/g)d" };
Идти
[ редактировать ]Go указывает, что строка является необработанной, используя обратный апостроф в качестве разделителя:
s := `C:\Foo\Bar.txt`
Необработанные строки могут содержать любые символы, кроме обратных кавычек; для обратной кавычки в необработанной строке нет escape-кода. Необработанные строки также могут занимать несколько строк, как в этом примере, где строки s
и t
эквивалентны:
s := `A string that
spans multiple
lines.`
t := "A string that\nspans multiple\nlines."
Питон
[ редактировать ]Python имеет аналогичную конструкцию, используя r
:
filePath = r"C:\Foo\Bar.txt"
Их также можно использовать вместе с тройными кавычками:
example = r"""First line : "C:\Foo\Bar.txt"
Second line : nothing"""
Руби
[ редактировать ]Ruby использует одинарную кавычку для обозначения необработанной строки:
filePath = 'C:\Foo\Bar.txt'
Он также имеет процентные литералы регулярных выражений с выбором разделителя, например Perl:
%r{ftp://[^/]*/pub/}
%r#ftp://[^/]*/pub/#
%r!ftp://[^/]*/pub/!
Ржавчина
[ редактировать ]Rust использует вариант r
префикс: [5]
"\x52"; // R
r"\x52"; // \x52
r#""foo""#; // "foo"
r##"foo #"# bar"##; // foo #"# bar
Буквально начинается с r
за которым следует любое количество #
, за которым следует один "
. Дальше "
содержащиеся в литерале, считаются частью литерала, если за ним не следует хотя бы столько же #
как используется после открытия r
. Таким образом, строковый литерал открывается с помощью r#"
не может иметь "#
в его содержании.
Скала
[ редактировать ]Scala позволяет использовать тройные кавычки, чтобы избежать путаницы:
val filePath = """C:\Foo\Bar.txt"""
val pubPattern = """ftp://[^/]*/pub/"""r
Тройные кавычки также позволяют использовать многострочные строки, как показано здесь:
val text = """First line,
second line."""
Но
[ редактировать ]Регулярные выражения Sed , особенно те, которые используют оператор «s», очень похожи на Perl (sed — предшественник Perl). Разделителем по умолчанию является «/», но можно использовать любой разделитель; по умолчанию s/regexp/replacement/
, но s:regexp:replacement:
также является допустимой формой. Например, чтобы найти каталог «pub» (как в примере Perl) и заменить его на «foo», по умолчанию (без косых черт) используется
s/ftp:\/\/[^\/]*\/pub\//foo/
Вместо этого использование восклицательного знака ("!") в качестве разделителя дает
s!ftp://[^/]*/pub/!foo!
См. также
[ редактировать ]Ссылки
[ редактировать ]- ^ Энди Лестер, Ричард Фоули (2005). Профессиональная отладка Perl . Энди Лестер, Ричард Фоули. п. 176. ИСБН 1-59059-454-1 .
- ^ Дэниел Голдман (февраль 2013 г.). Полное руководство по sed . ЕХДП Пресс. ISBN 978-1-939824-00-4 .
- ^ perlop на perldoc.perl.org.
- ^ Документы с отступом здесь
- ^ необработанные байтовые строковые литералы на сайте Rust-lang.org.