Строковый литерал или анонимная строка — это литерал для строкового значения в исходном коде компьютерной программы. Современные языки программирования обычно используют заключенную в кавычки последовательность символов, формально «разделители в квадратных скобках», как в x = "foo"
, где , "foo"
— это строковый литерал со значением foo
. Такие методы, как escape-последовательности, могут использоваться для избежания проблемы коллизии разделителей (проблемы со скобками) и позволяют встраивать разделители в строку. Существует множество альтернативных обозначений для указания строковых литералов, особенно в сложных случаях. Точная нотация зависит от рассматриваемого языка программирования. Тем не менее, существуют общие рекомендации, которым следуют большинство современных языков программирования.
Большинство современных языков программирования используют скобочные разделители (также сбалансированные разделители ) для указания строковых литералов. Двойные кавычки являются наиболее распространенными используемыми разделителями кавычек:
"Всем привет!"
Пустая строка буквально записывается парой кавычек без каких-либо символов между ними:
""
Некоторые языки либо разрешают, либо предписывают использование одинарных кавычек вместо двойных (строка должна начинаться и заканчиваться одним и тем же видом кавычек, а тип кавычек может давать или не давать немного различную семантику):
'Всем привет!'
Эти кавычки непарные (один и тот же символ используется как открывающий и закрывающий), что является пережитком технологии пишущих машинок , которые были предшественниками самых первых компьютерных устройств ввода и вывода.
С точки зрения регулярных выражений базовый строковый литерал в кавычках задается следующим образом:
"[^"]*"
Это означает, что строковый литерал записывается как: кавычка, за которой следует ноль, один или более символов, не являющихся кавычками, за которыми следует кавычка . На практике это часто усложняется экранированием, другими разделителями и исключением новых строк.
Ряд языков предусматривают парные разделители, в которых открывающий и закрывающий разделители различаются. Они также часто допускают вложенные строки, поэтому разделители могут быть встроены, если они парные, но все равно приводят к столкновению разделителей при встраивании непарного закрывающего разделителя. Примерами служат PostScript , который использует скобки, как в (The quick (brown fox))
и m4 , который использует обратную кавычку (`) в качестве начального разделителя и апостроф (') в качестве конечного разделителя. Tcl допускает как кавычки (для интерполированных строк), так и фигурные скобки (для необработанных строк), как в "The quick brown fox"
или {The quick {brown fox}}
; это вытекает из одинарных кавычек в оболочках Unix и использования фигурных скобок в C для составных операторов, поскольку блоки кода в Tcl синтаксически являются тем же самым, что и строковые литералы — то, что разделители являются парными, имеет важное значение для того, чтобы это было осуществимо.
Набор символов Unicode включает парные (отдельно открывающиеся и закрывающиеся) версии как одинарных, так и двойных кавычек:
"Всем привет!" 'Всем привет!' "Всем привет!" "Всем привет!"
Однако они используются редко, поскольку многие языки программирования не регистрируют их (исключением являются парные двойные кавычки, которые могут использоваться в Visual Basic .NET ). Непарные знаки предпочтительны для совместимости, поскольку их легче набирать на широком диапазоне клавиатур, и поэтому даже в языках, где они разрешены, многие проекты запрещают их использование в исходном коде.
Строковые литералы могут заканчиваться символами новой строки.
Одним из примеров являются параметры шаблона MediaWiki .
{{Навигационное окно |name=Нули |title=[[wikt:Null|Нуллы]] в [[вычислениях]] }}
Для многострочных строк может существовать специальный синтаксис.
В YAML строковые литералы могут быть заданы с помощью относительного расположения пробелов и отступов.
- title : Пример многострочной строки в теле YAML : | Это многострочная строка. Здесь могут появляться "специальные" метасимволы . Длина этой строки отображается отступом.
Некоторые языки программирования, такие как Perl и PHP, допускают строковые литералы без каких-либо разделителей в некоторых контекстах. В следующей программе Perl, например, red
, green
, и blue
являются строковыми литералами, но не заключены в кавычки:
%map = ( красный => 0x00f , синий => 0x0f0 , зеленый => 0xf00 );
Perl обрабатывает незарезервированные последовательности буквенно-цифровых символов как строковые литералы в большинстве контекстов. Например, следующие две строки Perl эквивалентны:
$y = "x" ; $y = x ;
В оригинальном языке программирования FORTRAN (например) строковые литералы записывались в так называемой нотации Холлерита , где за десятичным числом символов следовала буква H, а затем символы строки:
35 Пример строкового литерала Холлерита
Этот декларативный стиль записи отличается от кавычек с разделителями в квадратных скобках , поскольку не требует использования сбалансированных символов «в квадратных скобках» по обе стороны строки.
Преимущества:
Недостатки:
Однако это не является недостатком, если префикс генерируется алгоритмом, как это чаще всего и происходит. [ необходима цитата ]
C++ имеет два стиля строк, один из которых унаследован от C (разделен "
), а более безопасный — std::string
в стандартной библиотеке C++. std::string
Класс часто используется так же, как строковый литерал в других языках, и часто предпочтительнее строк в стиле C из-за его большей гибкости и безопасности. Но он имеет штраф производительности для строковых литералов, поскольку std::string
обычно динамически выделяет память и должен копировать в него строковый литерал в стиле C во время выполнения.
До C++11 не существовало литерала для строк C++ (C++11 допускает "this is a C++ string"s
использование the s
в конце литерала), поэтому использовался обычный синтаксис конструктора, например:
std::string str = "initializer syntax";
std::string str("converting constructor syntax");
std::string str = string("explicit constructor syntax");
Все они имеют одинаковую интерпретацию. Начиная с C++11, также появился новый синтаксис конструктора:
std::string str{"uniform initializer syntax"};
auto str = "constexpr literal syntax"s;
При использовании кавычек, если кто-то хочет представить сам разделитель в строковом литерале, он сталкивается с проблемой коллизии разделителей . Например, если разделитель — двойная кавычка, он не может просто представить саму двойную кавычку литералом """
, поскольку вторая кавычка интерпретируется как конец строкового литерала, а не как значение строки, и аналогично он не может написать, "This is "in quotes", but invalid."
поскольку средняя часть в кавычках вместо этого интерпретируется как вне кавычек. Существуют различные решения, наиболее общим из которых является использование управляющих последовательностей, таких как "\""
или "This is \"in quotes\" and properly escaped."
, но есть и много других решений.
Парные кавычки, такие как фигурные скобки в Tcl, допускают вложенные строки, такие как , {foo {bar} zork}
но в противном случае не решают проблему коллизии разделителей, поскольку несбалансированный закрывающий разделитель не может быть просто включен, как в {}}
.
Ряд языков, включая Pascal , BASIC , DCL , Smalltalk , SQL , J и Fortran , позволяют избежать конфликта разделителей, удваивая кавычки, которые должны быть частью самого строкового литерала:
'Эта строка Паскаля '' содержит два апострофа '' '
«Я сказал: «Вы меня слышите?»»
Некоторые языки, такие как Fortran , Modula-2 , JavaScript , Python и PHP допускают более одного разделителя кавычек; в случае двух возможных разделителей это известно как двойное кавычивание . Обычно это заключается в том, чтобы позволить программисту использовать либо одинарные кавычки, либо двойные кавычки взаимозаменяемо — каждый литерал должен использовать один или другой.
«Это яблоко Джона». «Я сказал: «Ты меня слышишь?»
Однако это не позволяет иметь один литерал с обоими разделителями. Это можно обойти, используя несколько литералов и используя конкатенацию строк :
«Я сказал: «Это ' + «Джона» + 'яблоко».
В Python есть конкатенация строковых литералов , поэтому последовательные строковые литералы объединяются даже без оператора, поэтому это можно сократить до:
«Я сказал: «Это яблоко Джона ».
C++11 ввел так называемые сырые строковые литералы . Они состоят, по сути, из
R"
end-of-string-id (
содержимое )
end-of-string-id "
,то есть после того, как R"
программист может ввести до 16 символов, за исключением пробельных символов, скобок или обратной косой черты, которые образуют end-of-string-id (его цель — повторяться для обозначения конца строки, сокращенно eos id ), затем требуется открывающая скобка (для обозначения конца eos id). Затем следует фактическое содержимое литерала: Могут использоваться любые символы последовательности (за исключением того, что она не может содержать закрывающую скобку, за которой следует eos id, за которым следует кавычка), и, наконец, — для завершения строки — требуется закрывающая скобка, eos id и кавычка. Простейший случай
такого литерала — с пустым содержимым и пустым eos id: R"()"
.
Сам eos id может содержать кавычки: R""(I asked, "Can you hear me?")""
является допустимым литералом (eos id "
здесь.)
Escape-последовательности не работают в необработанных строковых литералах.
D поддерживает несколько разделителей кавычек, такие строки начинаются с q"
plus открывающего разделителя и заканчиваются соответствующим закрывающим разделителем и "
. Доступные пары разделителей: ()
, <>
, {}
, и []
; непарный неидентификаторный разделитель является своим собственным закрывающим разделителем. Парные разделители вложены, поэтому это q"(A pair "()" of parens in quotes)"
допустимый литерал; пример с невложенным /
символом: q"/I asked, "Can you hear me?"/"
.
Подобно C++11, D допускает литералы в стиле here-document с идентификаторами конца строки:
q"
end-of-string-id newline content newline end-of-string-id "
В языке D end-of-string-id должен быть идентификатором (буквенно-цифровые символы).
В некоторых языках программирования, таких как sh и Perl , существуют различные разделители, которые обрабатываются по-разному, например, выполняют ли они интерполяцию строк или нет, поэтому необходимо проявлять осторожность при выборе разделителя для использования; см. различные виды строк ниже.
Дальнейшим расширением является использование множественных кавычек , что позволяет автору выбирать, какие символы должны определять границы строкового литерала.
Например, в Perl :
qq^Я сказал: «Ты меня слышишь?»^ qq@Я сказал: «Ты меня слышишь?»@ qq§Я сказал: «Ты меня слышишь?»§
все это дает желаемый результат. Хотя эта нотация более гибкая, ее поддерживают лишь немногие языки; кроме Perl, Ruby (под влиянием Perl) и C++11 также поддерживают их. Вариантом множественного кавычек является использование строк в стиле документа here .
Lua (начиная с версии 5.1) предоставляет ограниченную форму множественного кавычек, в частности, для вложения длинных комментариев или встроенных строк. Обычно используется [[
и ]]
для разграничения литеральных строк (начальный символ новой строки удаляется, в противном случае он остается необработанным), но открывающиеся скобки могут включать любое количество знаков равенства, и только закрывающиеся скобки с тем же количеством знаков закрывают строку. Например:
local ls = [=[ Эту нотацию можно использовать для путей Windows: local path = [[C:\Windows\Fonts]] ]=]
Множественное кавычки особенно полезны с регулярными выражениями , которые содержат обычные разделители, такие как кавычки, поскольку это позволяет избежать необходимости экранировать их. Ранним примером является sed , где в команде подстановки разделители косой черты по умолчанию могут быть заменены другим символом, как в .s/regex/replacement/
/
s,regex,replacement,
Другой вариант, который редко используется в современных языках, — это использование функции для построения строки, а не ее представления через литерал. Это обычно не используется в современных языках, поскольку вычисление выполняется во время выполнения, а не во время синтаксического анализа.
Например, ранние формы BASIC не включали escape-последовательности или какие-либо другие обходные пути, перечисленные здесь, и поэтому вместо этого требовалось использовать CHR$
функцию, которая возвращает строку, содержащую символ, соответствующий ее аргументу. В ASCII кавычка имеет значение 34, поэтому для представления строки с кавычками в системе ASCII нужно было бы написать
«Я сказал: « + CHR$ ( 34 ) + «Ты меня слышишь?» + CHR$ ( 34 )
В языке C аналогичная возможность доступна через sprintf
спецификатор %c
формата «character», хотя при наличии других обходных путей она, как правило, не используется:
char buffer [ 32 ]; snprintf ( buffer , sizeof buffer , "Это %cin кавычек.%c" , 34 , 34 );
Эти функции-конструкторы также могут использоваться для представления непечатаемых символов, хотя вместо этого обычно используются escape-последовательности. Подобный метод может использоваться в C++ с std::string
оператором строкообразования.
Escape-последовательности — это общий метод представления символов, которые в противном случае трудно представить напрямую, включая разделители, непечатаемые символы (например, возвраты на одну позицию), символы новой строки и пробельные символы (которые в противном случае невозможно различить визуально), и имеют долгую историю. Соответственно, они широко используются в строковых литералах, а добавление escape-последовательности (либо к одному символу, либо по всей строке) известно как экранирование .
Один символ выбирается в качестве префикса, чтобы задать кодировки для символов, которые трудно или невозможно включить напрямую. Чаще всего это обратная косая черта ; в дополнение к другим символам, ключевым моментом является то, что сама обратная косая черта может быть закодирована как двойная обратная косая черта \\
, а для разделенных строк сам разделитель может быть закодирован с помощью экранирования, например, с помощью \"
for ". Регулярное выражение для таких экранированных строк может быть задано следующим образом, как указано в спецификации ANSI C : [1] [a]
"(\\.|[^\\"])*"
означает "кавычка; за которой следует ноль или более экранированных символов (обратная косая черта, за которой следует что-то, возможно, обратная косая черта или кавычка), или неэкранированный, некавычковый символ; заканчивается кавычкой" – единственная проблема заключается в различении завершающей кавычки от кавычки, которой предшествует обратная косая черта, которая сама может быть экранирована. За обратной косой чертой может следовать несколько символов, например \uFFFF
, в зависимости от схемы экранирования.
Затем экранированная строка сама должна быть лексически проанализирована , преобразуя экранированную строку в неэкранированную строку, которую она представляет. Это делается во время фазы оценки общего лексического анализа компьютерного языка: оценщик лексического анализатора общего языка выполняет свой собственный лексический анализ для экранированных строковых литералов.
Среди прочего, должна быть возможность кодировать символ, который обычно завершает строковую константу, плюс должен быть какой-то способ указать сам escape-символ. Escape-последовательности не всегда красивы или просты в использовании, поэтому многие компиляторы также предлагают другие способы решения распространенных проблем. Escape-последовательности, однако, решают все проблемы с разделителями, и большинство компиляторов интерпретируют escape-последовательности. Когда escape-символ находится внутри строкового литерала, это означает «это начало escape-последовательности». Каждая escape-последовательность указывает один символ, который должен быть помещен непосредственно в строку. Фактическое количество символов, требуемых в escape-последовательности, варьируется. Escape-символ находится вверху/слева от клавиатуры, но редактор преобразует его, поэтому его нельзя напрямую вставить в строку. Обратная косая черта используется для представления escape-символа в строковом литерале.
Многие языки поддерживают использование метасимволов внутри строковых литералов. Метасимволы имеют различные интерпретации в зависимости от контекста и языка, но, как правило, являются своего рода «командой обработки» для представления печатных или непечатных символов.
Например, в строковом литерале C , если за обратной косой чертой следует буква, например, "b", "n" или "t", то это представляет непечатаемый символ возврата на одну позицию , новой строки или табуляции соответственно. Или если за обратной косой чертой следуют 1-3 восьмеричные цифры, то эта последовательность интерпретируется как представляющая произвольную кодовую единицу с указанным значением в кодировке литерала (например, соответствующий код ASCII для литерала ASCII). Позже это было расширено, чтобы разрешить более современную шестнадцатеричную нотацию кода символа:
"Я сказал: \t\t\x22Ты меня слышишь? \x22\n "
Примечание: не все последовательности в списке поддерживаются всеми анализаторами, и могут быть другие escape-последовательности, которых нет в списке.
Когда код на одном языке программирования встроен в другой, встроенные строки могут потребовать нескольких уровней экранирования. Это особенно распространено в регулярных выражениях и SQL-запросах в других языках или других языках внутри скриптов оболочки. Такое двойное экранирование часто трудно читать и создавать.
Неправильное кавычки вложенных строк может представлять уязвимость безопасности. Использование ненадежных данных, как в полях данных SQL-запроса, должно использовать подготовленные операторы для предотвращения атаки с внедрением кода . В PHP 2–5.3 была функция, называемая магическими кавычками , которая автоматически экранировала строки (для удобства и безопасности), но из-за проблем была удалена с версии 5.4 и далее.
Некоторые языки предоставляют метод указания того, что литерал должен обрабатываться без какой-либо специфической для языка интерпретации. Это позволяет избежать необходимости экранирования и дает более разборчивые строки.
Необработанные строки особенно полезны, когда необходимо экранировать общий символ, особенно в регулярных выражениях (вложенных как строковые литералы), где \
широко используется обратная косая черта, и в путях DOS/Windows , где обратная косая черта используется как разделитель пути. Обилие обратных косых черт известно как синдром наклонной зубочистки и может быть уменьшено с помощью необработанных строк. Сравните экранированные и необработанные имена путей в C#:
"Путь Windows: C:\\Foo\\Bar\\Baz\\" @"Путь Windows: C:\Foo\Bar\Baz\"
Крайние примеры возникают, когда они объединены – пути Uniform Naming Convention\\
начинаются с , и, таким образом, экранированное регулярное выражение, соответствующее имени UNC, начинается с 8 обратных косых черт, "\\\\\\\\"
, из-за необходимости экранирования строки и регулярного выражения. Использование необработанных строк сокращает это до 4 (экранирование в регулярном выражении), как в C# @"\\\\"
.
В документах XML разделы CDATA позволяют использовать символы, такие как & и <, без попытки анализатора XML интерпретировать их как часть структуры самого документа. Это может быть полезно при включении буквального текста и кода скрипта, чтобы сохранить документ правильно сформированным .
<![CDATA[ if (path!=null && depth<2) { add(path); } ]]>
Во многих языках строковые литералы могут содержать литеральные переводы строк, охватывающие несколько строк. В качестве альтернативы переводы строк могут быть экранированы, чаще всего как \n
. Например:
эхо 'foo bar'
и
echo -e "foo\nbar"
оба являются допустимыми bash, выдавая:
фубар
Языки, которые допускают литеральные переводы строк, включают bash, Lua, Perl, PHP, R и Tcl. В некоторых других языках строковые литералы не могут включать переводы строк.
Две проблемы с многострочными строковыми литералами — это начальные и конечные новые строки и отступы. Если начальные или конечные разделители находятся на отдельных строках, появляются дополнительные новые строки, а если нет, разделитель затрудняет чтение строки, особенно для первой строки, которая часто имеет отступ, отличный от остальных. Кроме того, литерал должен быть без отступа, поскольку начальные пробелы сохраняются — это нарушает поток кода, если литерал встречается в отступе кода.
Наиболее распространенным решением этих проблем являются строковые литералы в стиле here document . Формально говоря, here document — это не строковый литерал, а потоковый литерал или файловый литерал. Они берут начало в скриптах оболочки и позволяют передавать литерал в качестве входных данных внешней команде. Открывающий разделитель — это <<END
то, где END
может быть любое слово, а закрывающий разделитель находится END
на отдельной строке, выступая в качестве границы содержимого — это <<
связано с перенаправлением stdin из литерала. Поскольку разделитель произвольный, они также избегают проблемы столкновения разделителей. Они также позволяют удалять начальные символы табуляции с помощью вариантного синтаксиса, <<-END
хотя начальные пробелы не удаляются. Тот же синтаксис с тех пор был принят для многострочных строковых литералов в ряде языков, в частности Perl, и также называются here document и сохраняют синтаксис, несмотря на то, что являются строками и не требуют перенаправления. Как и в случае с другими строковыми литералами, для них иногда может быть указано другое поведение, например, интерполяция переменных.
Python, чьи обычные строковые литералы не допускают литеральных переносов строк, вместо этого имеет специальную форму строки, предназначенную для многострочных литералов, называемую тройными кавычками . Они используют тройной разделитель, либо '''
или """
. Эти литералы особенно используются для встроенной документации, известной как docstrings .
Tcl допускает буквальные переводы строк в строках и не имеет специального синтаксиса для работы с многострочными строками, хотя разделители могут размещаться в строках отдельно, а начальные и конечные переводы строк удаляются с помощью string trim
, в то время как string map
можно использовать для удаления отступов.
Несколько языков предоставляют конкатенацию строковых литералов , когда соседние строковые литералы неявно объединяются в один литерал во время компиляции. Это особенность C, [7] [8] C++, [9] D, [10] Ruby, [11] и Python, [12], которые скопировали ее из C. [13] Примечательно, что эта конкатенация происходит во время компиляции, во время лексического анализа (как фаза, следующая за начальной токенизацией), и контрастирует как с конкатенацией строк во время выполнения (обычно с +
оператором) [14] , так и с конкатенацией во время сворачивания констант , которая происходит во время компиляции, но на более поздней фазе (после анализа фраз или «парсинга»). Большинство языков, таких как C#, Java [15] и Perl, не поддерживают неявную конкатенацию строковых литералов и вместо этого требуют явной конкатенации, например, с +
оператором (это также возможно в D и Python, но недопустимо в C/C++ – см. ниже); в этом случае конкатенация может происходить во время компиляции, посредством свертывания констант, или может быть отложена до времени выполнения.
В языке C, откуда и произошли эта концепция и термин, конкатенация строковых литералов была введена по двум причинам: [16]
На практике это позволяет выполнять конкатенацию строк на ранних этапах компиляции («перевод», в частности, как часть лексического анализа), не требуя анализа фраз или сворачивания констант. Например, следующие примеры являются допустимыми для C/C++:
char * s = "привет, " "мир" ; printf ( "привет, " "мир" );
Однако следующие утверждения недействительны:
char * s = "привет, " + "мир" ; printf ( "привет, " + "мир" );
Это связано с тем, что строковые литералы имеют тип массива (C ) или (C++), который не может быть добавлен; в большинстве других языков это не является ограничением.char [n]
const char [n]
Это особенно важно при использовании в сочетании с препроцессором C , чтобы обеспечить возможность вычисления строк после предварительной обработки, особенно в макросах. [13] Простой пример:
char * file_and_message = __FILE__ ": сообщение" ;
будет (если файл называется ac) расширяться до:
char * file_and_message = "ac" ": сообщение" ;
которые затем объединяются, что эквивалентно:
char * file_and_message = "ac: сообщение" ;
Распространенным вариантом использования является построение строк формата printf или scanf, где спецификаторы формата задаются макросами. [18] [19]
Более сложный пример использует стрингификацию целых чисел (препроцессором) для определения макроса, который расширяется до последовательности строковых литералов, которые затем объединяются в один строковый литерал с именем файла и номером строки: [20]
#define STRINGIFY(x) #x #define TOSTRING(x) STRINGIFY(x) #define AT __FILE__ ":" TOSTRING(__LINE__)
Помимо синтаксических требований C/C++, неявная конкатенация является формой синтаксического сахара , упрощая разбиение строковых литералов на несколько строк, избегая необходимости продолжения строки (через обратные косые черты) и позволяя добавлять комментарии к частям строк. Например, в Python можно комментировать регулярное выражение следующим образом: [21]
re . compile ( "[A-Za-z_]" # буква или подчеркивание "[A-Za-z0-9_]*" # буква, цифра или подчеркивание )
Неявная конкатенация строк не требуется современным компиляторам, которые реализуют свертку констант, и приводит к труднообнаружимым ошибкам из-за непреднамеренной конкатенации из-за пропуска запятой, особенно в вертикальных списках строк, как в следующем примере:
l = [ 'foo' , 'bar' 'zork' ]
Соответственно, он не используется в большинстве языков, и его было предложено исключить из D [22] и Python. [13] Однако удаление этой функции нарушает обратную совместимость, а замена ее оператором конкатенации приводит к проблемам приоритета — конкатенация строковых литералов происходит во время лексического анализа, до оценки оператора, но конкатенация посредством явного оператора происходит одновременно с другими операторами, поэтому приоритет является проблемой, потенциально требующей скобок для обеспечения желаемого порядка оценки.
Более тонкая проблема заключается в том, что в C и C++ [23] существуют различные типы строковых литералов, и их объединение имеет поведение, определяемое реализацией, что представляет потенциальную угрозу безопасности. [24]
Некоторые языки предоставляют более одного вида литералов, которые ведут себя по-разному. Это в частности используется для указания необработанных строк (без экранирования) или для отключения или включения интерполяции переменных, но имеет и другие применения, например, для различения наборов символов. Чаще всего это делается путем изменения символа кавычек или добавления префикса или суффикса. Это сопоставимо с префиксами и суффиксами для целочисленных литералов , например, для указания шестнадцатеричных чисел или длинных целых чисел.
Один из самых старых примеров — скрипты оболочки, где одинарные кавычки обозначают необработанную строку или «литеральную строку», а двойные кавычки обозначают управляющие последовательности и интерполяцию переменных.
Например, в Python необработанные строки предваряются символом r
or R
– сравните 'C:\\Windows'
с r'C:\Windows'
(хотя необработанная строка Python не может заканчиваться нечетным числом обратных косых черт). Python 2 также различает два типа строк: 8-битные строки ASCII («байты») (по умолчанию), явно обозначенные префиксом b
or B
, и строки Unicode, обозначенные префиксом u
or U
. [25] в то время как в Python 3 строки по умолчанию являются Unicode, а байты являются отдельным bytes
типом, который при инициализации кавычками должен иметь префикс b
.
Обозначение необработанных строк в C# называется @-цитированием.
@"C:\Foo\Bar\Baz\"
Хотя это отключает экранирование, оно разрешает двойные кавычки, что позволяет представлять кавычки внутри строки:
@"Я сказал: ""Привет."""
C++11 допускает необработанные строки, строки юникода (UTF-8, UTF-16 и UTF-32) и строки широких символов, определяемые префиксами. Он также добавляет литералы для существующего C++ string
, который обычно предпочтительнее существующих строк в стиле C.
В Tcl строки, разделенные фигурными скобками, являются литеральными, тогда как строки, разделенные кавычками, имеют экранирование и интерполяцию.
Perl имеет широкий спектр строк, которые более формально считаются операторами и известны как операторы кавычек и кавычек-подобных операторов . Они включают как обычный синтаксис (фиксированные разделители), так и общий синтаксис, который позволяет выбирать разделители; они включают: [26]
'' "" `` // м// qr// s/// y // / q{} qq{} qx{} qw{} м {} qr{} s{}{} tr {}{} y {}{}
REXX использует символы суффикса для указания символов или строк с использованием их шестнадцатеричного или двоичного кода. Например,
'20' х "0010 0000" б "00100000" б
все они выдают символ пробела , избегая вызова функции X2C(20)
.
В некоторых языках строковые литералы могут содержать заполнители, ссылающиеся на переменные или выражения в текущем контексте , которые вычисляются (обычно во время выполнения). Это называется интерполяцией переменных или, в более общем смысле, интерполяцией строк . Языки, поддерживающие интерполяцию, обычно отличают интерполированные строковые литералы от неинтерполированных. Например, в sh-совместимых оболочках Unix (а также в Perl и Ruby) строки в двойных кавычках (разделенные кавычками, ") интерполируются, а строки в одинарных кавычках (разделенные апострофами, ') — нет. Неинтерполированные строковые литералы иногда называют «сырыми строками», но это отличается от «сырой строки» в смысле экранирования. Например, в Python строка с префиксом r
или R
не имеет экранирования или интерполяции, обычная строка (без префикса) имеет экранирование, но не имеет интерполяции, а строка с префиксом f
или F
имеет экранирование и интерполяцию.
Например, следующий код Perl :
$name = "Нэнси" ; $greeting = "Привет, мир" ; print "$name сказал приветствие $толпе людей." ;
выдает результат:
Нэнси сказала толпе людей: «Привет, мир!»
В этом случае метасимвол ($) (не путать с символом в операторе присваивания переменной) интерпретируется как указание на интерполяцию переменной и требует экранирования, если его необходимо вывести буквально.
Это следует противопоставить функции printf
, которая выдает тот же результат, используя следующую запись:
printf "%s сказал %s толпе людей." , $name , $greeting ;
но не выполняет интерполяцию: %s
является заполнителем в строке формата printf , но сами переменные находятся за пределами строки.
Это контрастирует с «сырыми» строками:
print '$name сказал $приветствие толпе людей.' ;
которые производят вывод вроде:
$name сказал, приветствуя толпу людей.
Здесь символы $ не являются метасимволами и не интерпретируются как имеющие иное значение, кроме обычного текста.
Языки, которым не хватает гибкости в определении строковых литералов, делают особенно громоздким написание программного кода, который генерирует другой программный код. Это особенно верно, когда язык генерации совпадает или похож на выходной язык.
Например:
Тем не менее, некоторые языки особенно хорошо приспособлены для создания такого рода самоподобных выходных данных, особенно те, которые поддерживают несколько вариантов предотвращения коллизий разделителей.
Использование строковых литералов в качестве кода, генерирующего другой код, может иметь неблагоприятные последствия для безопасности, особенно если вывод основан хотя бы частично на ненадежном пользовательском вводе. Это особенно актуально в случае веб-приложений, где злоумышленники могут воспользоваться такими уязвимостями, чтобы подорвать работу приложения, например, путем проведения атаки с использованием SQL-инъекции .