Из Википедии, бесплатной энциклопедии
  (Перенаправлен из буквальной строки )
Перейти к навигации Перейти к поиску

Строковый литерал или анонимная строка [1] представляет собой тип литерала в программировании для представления строки значения в пределах исходного кода в виде компьютерной программы . Чаще всего в современных языках это последовательность символов в кавычках (формально « разделители в квадратных скобках »), например x = "foo", где "foo"- строковый литерал со значением foo- кавычки не являются частью значения, и необходимо использовать такой метод, как escape-последовательности. чтобы избежать проблемы коллизии разделителей и разрешить разделителисами должны быть встроены в строку. Однако существует множество альтернативных обозначений для указания строковых литералов, особенно в более сложных случаях, и точное обозначение зависит от конкретного рассматриваемого языка программирования . Тем не менее, есть некоторые общие рекомендации, которым следует большинство современных языков программирования.

Синтаксис [ править ]

Разделители в квадратных скобках [ править ]

Большинство современных языков программирования используют разделители скобок (также сбалансированные разделители ) для указания строковых литералов. Чаще всего используются двойные кавычки :

 "Всем привет!"

Пустая строка буквально записывается парой кавычек без каких-либо символов между ними:

 ""

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

 'Всем привет!'

Эти кавычки не являются парными (один и тот же символ используется как открывающий и закрывающий), что является пережитком технологии пишущей машинки, которая была предшественницей самых ранних компьютерных устройств ввода и вывода.

В терминах регулярных выражений базовый строковый литерал в кавычках имеет следующий вид:

"[^"] * "

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

Парные разделители [ править ]

В ряде языков предусмотрены парные разделители, в которых открывающие и закрывающие разделители различны. Они также часто допускают вложенные строки, поэтому разделители могут быть встроены, если они являются парными, но все же приводят к конфликту разделителей для встраивания непарного закрывающего разделителя. Примеры включают PostScript , в котором используются круглые скобки, такие как in (The quick (brown fox))и m4 , в котором обратный апостроф (`) используется в качестве начального разделителя, а апостроф (') - в качестве конечного разделителя. Tcl допускает как кавычки (для интерполированных строк), так и фигурные скобки (для необработанных строк), как в "The quick brown fox"или {The quick {brown fox}}; это происходит из одинарных кавычек в оболочках Unix и использования фигурных скобок в C для составных операторов, поскольку блоки кода в Tcl синтаксически идентичны строковым литералам - парные разделители необходимы для того, чтобы это стало возможным.

Хотя набор символов Unicode включает парные (отдельные открывающие и закрывающие) версии как одинарных, так и двойных кавычек, используемых в тексте, в основном на других языках, кроме английского, они редко используются в языках программирования (потому что ASCII является предпочтительным, и они не включены в ASCII):

 "Всем привет!" 'Всем привет!' "Всем привет!" "Всем привет!"

Парные двойные кавычки можно использовать в Visual Basic .NET , но многие другие языки программирования не принимают их. Непарные метки предпочтительнее для совместимости, поскольку их легче набирать на широком спектре клавиатур, и поэтому даже на языках, где они разрешены, многие проекты запрещают их использование в качестве исходного кода.

Разделители пробелов [ править ]

Строковые литералы могут заканчиваться символами новой строки.

Одним из примеров являются параметры шаблона MediaWiki .

 {{Navbox | name = Пустые значения | title = [[wikt: Null | Nulls]] в [[вычисления]] }}

Для многострочных строк может быть специальный синтаксис.

В YAML строковые литералы могут задаваться относительным расположением пробелов и отступов.

 -  title :  Пример многострочной строки в  теле YAML :  |  Это многострочная строка.  здесь могут  появляться  "специальные" метасимволы . Размер этой строки представлен отступом.

Без разделителей [ править ]

Некоторые языки программирования, такие как Perl, JavaScript и PHP, допускают строковые литералы без каких-либо разделителей в некоторых контекстах. В следующих программах Perl и JavaScript, например, red, green, и blueстроковые литералы, но без кавычек:

% map  =  ( красный  =>  0x00f ,  синий  =>  0x0f0 ,  зеленый  =>  0xf00 );
map  =  { красный :  0x00f ,  синий :  0x0f0 ,  зеленый :  0xf00 };

Perl обрабатывает незарезервированные последовательности буквенно-цифровых символов как строковые литералы в большинстве контекстов. Например, следующие две строки Perl эквивалентны:

$ y  =  "х" ; $ y  =  x ;

Декларативная запись [ править ]

В исходном языке программирования FORTRAN (например) строковые литералы были записаны в так называемой нотации Холлерита , где за десятичным счетом количества символов следовала буква H, а затем символы строки:

35 H  Пример  строкового литерала Холлерита  

Этот декларативный стиль обозначений контрастирует с заключением в квадратные скобки разделителя в кавычках, поскольку он не требует использования сбалансированных «заключенных в квадратные скобки» символов по обе стороны от строки.

Преимущества:

  • исключает поиск по тексту (для символа-разделителя) и, следовательно, требует значительно меньше накладных расходов
  • позволяет избежать проблемы коллизии разделителей
  • позволяет включать метасимволы, которые в противном случае могли бы быть ошибочно приняты за команды
  • может использоваться для достаточно эффективного сжатия данных в текстовых строках [ необходима ссылка ]

Недостатки:

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

Однако это не является недостатком, когда префикс генерируется алгоритмом, как это наиболее вероятно. [ необходима цитата ]

Функции конструктора [ править ]

В C ++ есть два стиля строк: один унаследован от C (с разделителями "), а более безопасный - std::stringв стандартной библиотеке C ++. std::stringКласс часто используется таким же образом строковые будет использоваться на других языках, и часто предпочитают строки C-стиль для его большей гибкости и безопасности. Но это приводит к снижению производительности для строковых литералов, поскольку std::stringобычно память распределяется динамически и во время выполнения необходимо копировать в нее строковый литерал в стиле C.

До C ++ 11 не было литерала для строк C ++ (C ++ 11 допускает "this is a C++ string"sиспользование 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 имеет конкатенацию строковых литералов , поэтому последовательные строковые литералы объединяются даже без оператора, поэтому это можно свести к:

 Я сказал: «Это яблоко Джона» .

D поддерживает несколько разделителей кавычек, при этом такие строки начинаются с q"[и заканчиваются ]"или аналогичным образом для другого символа-разделителя (любого из () <> {} или []). D также поддерживает здесь строки в стиле документа через аналогичный синтаксис.

В некоторых языках программирования, таких как sh и Perl , существуют разные разделители, которые обрабатываются по-разному, например, выполнение строковой интерполяции или нет, и поэтому следует проявлять осторожность при выборе того, какой разделитель использовать; см. различные типы строк ниже.

Множественное цитирование [ править ]

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

Например, в Perl :

qq ^ Я сказал: «Ты меня слышишь?» ^ qq @ Я сказал: «Ты меня слышишь?» @ qq§ Я сказал: «Ты меня слышишь?» §

все дают желаемый результат. Хотя эта нотация более гибкая, ее поддерживают несколько языков; кроме Perl, они также поддерживаются Ruby (под влиянием Perl) и C ++ 11 . В C ++ 11 необработанные строки могут иметь различные разделители, начиная с R"delimiter(и заканчивая )delimiter". Разделитель может иметь длину от нуля до 16 символов и может содержать любой член базового исходного набора символов, кроме символов пробела, круглых скобок или обратной косой черты. Вариантом множественного цитирования является использование здесь строк в стиле документа .

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«символ» спецификатор формата, хотя и в присутствии других обходных путей это , как правило , не используется:

sprintf ( «Это% cin quotes.% c» ,  34 ,  34 );

Эти функции-конструкторы также могут использоваться для представления непечатаемых символов, хотя вместо них обычно используются escape-последовательности. Аналогичный прием можно использовать в C ++ с std::stringоператором строкового преобразования.

Последовательности выхода [ править ]

Escape-последовательности - это общий метод представления символов, которые иначе трудно представить напрямую, включая разделители, непечатаемые символы (например, обратные пробелы), символы новой строки и пробельные символы (которые в противном случае невозможно различить визуально), и имеют долгую историю. Соответственно, они широко используются в строковых литералах, а добавление escape-последовательности (либо к одному символу, либо по всей строке) известно как экранирование .

Один символ выбирается в качестве префикса, чтобы задать кодировки для символов, которые сложно или невозможно включить напрямую. Чаще всего это обратная косая черта ; Помимо других символов, ключевым моментом является то, что сама обратная косая черта может быть закодирована как двойная обратная косая черта, \\а для строк с разделителями сам разделитель может быть закодирован путем экранирования, например, \"для ". Регулярное выражение для таких экранированных строк может быть задано следующим образом , как указано в спецификации ANSI C : [2] [a]

"(\\. | [^ \\"]) * »

означает «кавычка; за которым следует ноль или более либо экранированного символа (обратная косая черта, за которым следует что-то, возможно, обратная косая черта или кавычка), либо неэкранирующего символа без кавычек; оканчивается цитатой» - единственная проблема заключается в различении завершающая цитата из кавычки, которой предшествует обратная косая черта, которая сама может быть экранирована. За обратной косой чертой могут следовать несколько символов, например \uFFFF, в зависимости от схемы экранирования.

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

Помимо прочего, должна существовать возможность кодирования символа, который обычно завершает строковую константу, плюс должен быть какой-то способ указать сам escape-символ. Escape-последовательности не всегда красивы или просты в использовании, поэтому многие компиляторы также предлагают другие средства решения распространенных проблем. Однако escape-последовательности решают все проблемы с разделителями, и большинство компиляторов интерпретируют escape-последовательности. Когда escape-символ находится внутри строкового литерала, это означает, что «это начало escape-последовательности». Каждая escape-последовательность определяет один символ, который должен быть помещен непосредственно в строку. Фактическое количество символов, требуемых в escape-последовательности, варьируется. Управляющий символ находится вверху / слева на клавиатуре, но редактор переведет его, поэтому его нельзя напрямую записать в строку.Обратная косая черта используется для представления escape-символа в строковом литерале.

Многие языки поддерживают использование метасимволов внутри строковых литералов. Метасимволы имеют разную интерпретацию в зависимости от контекста и языка, но обычно представляют собой своего рода «команду обработки» для представления печатных или непечатаемых символов.

Например, в строковом литерале C , если за обратной косой чертой следует буква, такая как «b», «n» или «t», то это представляет собой непечатаемый символ возврата , новую строку или символ табуляции соответственно. Или, если за обратной косой чертой следуют 1-3 восьмеричных цифры, то эта последовательность интерпретируется как представление произвольного символа с указанным кодом ASCII . Позже это было расширено, чтобы позволить более современную нотацию шестнадцатеричного кода символа:

"Я сказал: \ t \ t \ x22Ca n ты меня слышишь? \ 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 [если (путь! = Ноль && глубина <2) {добавить (путь); }]]>

Многострочные строковые литералы [ править ]

Во многих языках строковые литералы могут содержать буквальные символы новой строки, занимающие несколько строк. Кроме того, символы новой строки могут быть экранированы, чаще всего как \n. Например:

эхо  'foo bar'

а также

echo -e "foo \ nbar"

оба являются действительными bash, производя:

фубар

Языки, допускающие буквальные символы новой строки, включают bash, Lua, Perl, PHP, R и Tcl. В некоторых других языках строковые литералы не могут включать символы новой строки.

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

Наиболее частым решением этих проблем являются строковые литералы в стиле документа . Формально говоря, здесь документ - это не строковый литерал, а литерал потока или литерал файла. Они берут начало в сценариях оболочки и позволяют использовать литерал в качестве входных данных для внешней команды. Открытие разделитель , <<ENDгде ENDможет быть любое слово, и закрывающий ограничитель ENDна отдельной строке, выступающей в качестве границы Содержание - <<это связано с перенаправлением стандартного ввода с буквальным. Из-за того, что разделитель является произвольным, это также позволяет избежать проблемы коллизии разделителей. Они также позволяют удалять начальные вкладки с помощью синтаксиса вариантов.<<-ENDхотя ведущие пробелы не удаляются. С тех пор тот же синтаксис был принят для многострочных строковых литералов на нескольких языках, в первую очередь на Perl, которые также называются здесь документами и сохраняют синтаксис, несмотря на то, что они являются строками и не связаны с перенаправлением. Как и в случае с другими строковыми литералами, они иногда могут иметь другое поведение, например интерполяцию переменных.

Python, чьи обычные строковые литералы не допускают буквальные символы новой строки, вместо этого имеет специальную форму строки, предназначенную для многострочных литералов, которая называется тройным цитированием . В них используется тройной разделитель либо '''или """. Эти литералы особенно используются для встроенной документации, известной как строки документации .

Tcl допускает буквальные символы новой строки в строках и не имеет специального синтаксиса, помогающего с многострочными строками, хотя разделители могут быть помещены в строки сами по себе, а ведущие и конечные символы новой строки удаляются через string trim, в то время как string mapмогут использоваться для удаления отступов.

Конкатенация строковых литералов [ править ]

Некоторые языки обеспечивают конкатенацию строковых литералов , когда смежные строковые литералы неявно объединяются в один литерал во время компиляции. Это особенность C, [8] [9] C ++, [10] D, [11] Ruby, [12] и Python, [13], которые скопировали ее из C. [14] Примечательно, что эта конкатенация происходит при компиляции время, во время лексического анализа (как фаза после начальной токенизации), и контрастирует как с конкатенацией строк во время выполнения (обычно с +оператором) [15], так и с конкатенацией во время сворачивания констант., который происходит во время компиляции, но на более позднем этапе (после анализа фразы или «синтаксического анализа»). Большинство языков, таких как C #, Java [16] и Perl, не поддерживают неявную конкатенацию строковых литералов, а вместо этого требуют явной конкатенации, такой как с +оператором (это также возможно в D и Python, но недопустимо в C / C ++ - см. ниже); в этом случае конкатенация может происходить во время компиляции посредством сворачивания констант или может быть отложена до времени выполнения.

Мотивация [ править ]

В C, откуда произошли понятие и термин, конкатенация строковых литералов была введена по двум причинам: [17]

  • Чтобы позволить длинным строкам охватывать несколько строк с правильным отступом, в отличие от продолжения строки, которое разрушает схему отступов; а также
  • Разрешить создание строковых литералов макросами (через преобразование в строку ). [18]

На практике это позволяет объединять строки на ранних этапах компиляции («перевод», в частности, как часть лексического анализа), не требуя анализа фраз или сворачивания констант. Например, допустимы следующие C / C ++:

char  * s  =  "привет",  "мир" ; printf ( "привет",  "мир" );

Однако следующее недействительно:

char  * s  =  "привет"  +  "мир" ; printf ( "привет"  +  "мир" );

Это потому , что строковые литералы имеют тип массива , (С) или (С ++), которые не могут быть добавлены; это не ограничение для большинства других языков.char [n]const char [n]

Это особенно важно при использовании в сочетании с препроцессором C , чтобы позволить вычислять строки после предварительной обработки, особенно в макросах. [14] В качестве простого примера:

char  * file_and_message  =  __FILE__  ": сообщение" ;

будет (если файл называется ac) расширится до:

char  * file_and_message  =  "ac"  ": сообщение" ;

который затем объединяется, что эквивалентно:

char  * file_and_message  =  "ac: сообщение" ;

Типичный вариант использования - создание строк формата printf или scanf , где спецификаторы формата задаются макросами. [19] [20]

В более сложном примере используется преобразование целых чисел в строку (препроцессором) для определения макроса, который расширяется до последовательности строковых литералов, которые затем объединяются в один строковый литерал с именем файла и номером строки: [21]

#define STRINGIFY (x) #x #define TOSTRING (x) STRINGIFY (x) #define AT __FILE__ ":" TOSTRING (__ LINE__)

Помимо синтаксических требований C / C ++, неявная конкатенация - это форма синтаксического сахара , упрощающая разделение строковых литералов на несколько строк, избегая необходимости продолжения строки (через обратную косую черту) и позволяя добавлять комментарии к частям строк. Например, в Python можно прокомментировать регулярное выражение следующим образом: [22]

ре . compile ( "[A-Za-z_]"  # буква или  знак  подчеркивания "[A-Za-z0-9 _] *" # буква, цифра или  знак подчеркивания )

Проблемы [ править ]

Неявная конкатенация строк не требуется современными компиляторами, которые реализуют сворачивание констант и вызывают трудно обнаруживаемые ошибки из-за непреднамеренной конкатенации из-за пропуска запятой, особенно в вертикальных списках строк, например:

l  =  [ 'foo' ,  'bar'  'zork' ]

Соответственно, он не используется в большинстве языков, и его предлагали исключить из D [23] и Python. [14] Однако удаление этой функции нарушает обратную совместимость, и замена ее оператором конкатенации создает проблемы с приоритетом - конкатенация строковых литералов происходит во время лексирования, до оценки оператора, но конкатенация с помощью явного оператора происходит одновременно с другими операторами. , следовательно, приоритет - это проблема, которая может потребовать скобок для обеспечения желаемого порядка оценки.

Более тонкая проблема заключается в том, что в C и C ++ [24] существуют разные типы строковых литералов, и их конкатенация имеет поведение, определяемое реализацией, что создает потенциальную угрозу безопасности. [25]

Различные виды строк [ править ]

Некоторые языки предоставляют более одного вида литералов, которые имеют разное поведение. Это, в частности, используется для обозначения необработанных строк (без экранирования) или для отключения или включения интерполяции переменных, но имеет и другие применения, такие как различение наборов символов. Чаще всего это делается путем изменения символа цитирования или добавления префикса или суффикса. Это сопоставимо с префиксами и суффиксами для целочисленных литералов , например для обозначения шестнадцатеричных чисел или длинных целых чисел.

Один из самых старых примеров - сценарии оболочки, где одинарные кавычки обозначают необработанную строку или «буквальную строку», а двойные кавычки содержат escape-последовательности и интерполяцию переменных.

Например, в Python необработанным строкам предшествует rили R- compare 'C:\\Windows'with r'C:\Windows'(хотя необработанная строка Python не может заканчиваться нечетным числом обратных косых черт). Python 2 также различает два типа строк: 8-битные строки ASCII («байты») (по умолчанию), явно обозначенные префиксом bили B, и строки Unicode, обозначенные префиксом uили U. [26] в то время как в Python 3 строки по умолчанию являются Unicode, а байты - это отдельный bytesтип, который при инициализации кавычками должен иметь префикс b.

Обозначение C # для необработанных строк называется @ -quoting.

@ "C: \ Foo \ Bar \ Baz \"

Хотя это отключает экранирование, оно позволяет использовать двойные кавычки, которые позволяют представлять кавычки внутри строки:

@ "Я сказал:" "Привет." ""

C ++ 11 допускает необработанные строки, строки Unicode (UTF-8, UTF-16 и UTF-32) и строки широких символов, определяемые префиксами. Он также добавляет литералы для существующего C ++ string, который обычно предпочтительнее существующих строк в стиле C.

В Tcl строки, разделенные фигурными скобками, являются буквальными, а строки, разделенные кавычками, имеют экранирование и интерполяцию.

Perl имеет широкий спектр строк, которые формально считаются операторами и известны как кавычки и операторы, подобные кавычкам . К ним относятся как обычный синтаксис (фиксированные разделители), так и общий синтаксис, который позволяет выбирать разделители; к ним относятся: [27]

''  ""  `  //  m //  qr //  s ///  y // / q {}  qq {}  qx {}  qw {}  m {}  qr {}  s {} {}  tr {} {}  y {} {}

REXX использует символы суффикса для указания символов или строк, используя их шестнадцатеричный или двоичный код. Например,

'20' х«0010 0000» б«00100000» б

все выдают пробел , избегая вызова функции X2C(20).

Интерполяция переменных [ править ]

Языки различаются по тому, как интерпретировать строковые литералы как «сырые» или «интерполированные переменные». Интерполяция переменных - это процесс вычисления выражения, содержащего одну или несколько переменных, и возврата вывода, в котором переменные заменяются соответствующими значениями в памяти. В sh-совместимых оболочках Unix (а также Perl и Ruby) строки, разделенные кавычками ("), интерполируются, а строки, разделенные апострофом ('), - нет. Например, следующий код Perl :

$ name  =  "Нэнси" ; $ welcome  =  "Привет, мир" ; print  "$ name сказал $ приветствие толпе людей." ;

производит вывод:

Нэнси сказала «Привет, мир» толпе.

Символ сигилы ($) интерпретируется как указание на интерполяцию переменных.

Точно так же printfфункция производит тот же результат, используя такие обозначения, как:

printf  "% s сказал% s толпе." ,  $ имя ,  $ приветствие ;

Метасимволы (% s) указывают на интерполяцию переменных.

В отличие от "сырых" строк:

print  '$ name сказал $ приветствие толпе людей.' ;

которые производят такой вывод:

$ name сказал $ приветствие толпе людей.

Здесь символы $ не являются сигилами и не интерпретируются как имеющие какое-либо значение, кроме обычного текста.

Встраивание исходного кода в строковые литералы [ править ]

Языки, в которых отсутствует гибкость при указании строковых литералов, делают особенно громоздким написание программного кода, который генерирует другой программный код. Это особенно верно, когда язык генерации такой же или похож на язык вывода.

Например:

  • написание кода для создания quines
  • создание языка вывода из веб-шаблона ;
  • использование XSLT для генерации XSLT или SQL для генерации большего количества SQL
  • создание PostScript- представления документа для печати из приложения для обработки документов, написанного на C или другом языке.
  • написание шейдеров

Тем не менее, некоторые языки особенно хорошо адаптированы для создания такого рода самоподобного вывода, особенно те, которые поддерживают несколько вариантов предотвращения коллизии разделителей.

Использование строковых литералов в качестве кода, генерирующего другой код, может иметь неблагоприятные последствия для безопасности, особенно если выходные данные основаны, по крайней мере, частично на вводе ненадежных пользователей. Это особенно актуально в случае веб-приложений, где злоумышленники могут воспользоваться такими слабыми местами, чтобы подорвать работу приложения, например, путем организации атаки с использованием SQL-инъекции .

См. Также [ править ]

  • Символьный литерал
  • XML-литералы
  • Sigil (компьютерное программирование)

Заметки [ править ]

  1. ^ Приведенное здесь регулярное выражение само по себе не цитируется и не экранируется, чтобы избежать путаницы.

Ссылки [ править ]

  1. ^ «Введение в Java - MFC 158 G» . Строковые литералы (или константы) называются анонимными строками.
  2. ^ "Грамматика ANSI C (Lex)" . liu.se . Проверено 22 июня +2016 .
  3. ^ a b «Приложение Б. Символы, строки и правила экранирования» . realworldhaskell.org . Проверено 22 июня +2016 .
  4. ^ a b «Строка» . mozilla.org . Проверено 22 июня +2016 .
  5. ^ a b c d e f g h i j k l m "Escape Sequences (C)" . microsoft.com . Проверено 22 июня +2016 .
  6. ^ a b «Обоснование международного стандарта - языки программирования - C» (PDF) . 5.10. Апрель 2003. С. 52, 153–154, 159. Архивировано (PDF) из оригинала 06.06.2016 . Проверено 17 октября 2010 .
  7. ^ "6.35 The Character <ESC> in Constants" , GCC 4.8.2 Manual , получено 8 марта 2014 г.
  8. ^ Проект стандарта C11, проект комитета WG14 N1570 - 12 апреля 2011 г. , 5.1.1.2 Этапы перевода, стр. 11: «6. Смежные лексемы строковых литералов объединяются».
  9. ^ Синтаксис C: конкатенация строковых литералов
  10. ^ Проект стандарта C ++ 11 , «Рабочий проект стандарта языка программирования C ++» (PDF) . , 2.2 Фазы трансляции [lex.phases], с. 17: «6. Смежные лексемы строковых литералов объединяются». и 2.14.5 Строковые литералы [lex.string], примечание 13, с. 28–29: «На этапе перевода 6 (2.2) смежные строковые литералы объединяются».
  11. ^ D Язык программирования , лексический анализ , «Строковые литералы»: «Смежные строки объединяются оператором ~ или простым сопоставлением:»
  12. ^ ruby: Язык программирования Ruby, Язык программирования Ruby, 2017-10-19 , получено 2017-10-19
  13. ^ Справочник по языку Python, 2. Лексический анализ, 2.4.2. Конкатенация строковых литералов : «Допускается несколько смежных строковых литералов (разделенных пробелами), возможно, с использованием различных соглашений о кавычках, и их значение такое же, как и их конкатенация».
  14. ^ a b c Идеи Python, « Неявная конкатенация строковых литералов считается вредной? », Гвидо ван Россум, 10 мая 2013 г.
  15. ^ Справочник по языку Python, 2. Лексический анализ, 2.4.2. Конкатенация строковых литералов : «Обратите внимание, что эта функция определена на синтаксическом уровне, но реализована во время компиляции. Оператор '+' должен использоваться для конкатенации строковых выражений во время выполнения».
  16. ^ «Строки (Учебники по Java ™> Изучение языка Java> Числа и строки)» . Docs.oracle.com . 2012-02-28 . Проверено 22 июня 2016 .
  17. ^ Обоснование языка программирования ANSI C . Silicon Press. 1990. стр. 31 . ISBN 0-929306-07-4., 3.1.4 Строковые литералы: "Длинную строку можно продолжить на несколько строк, используя продолжение строки с обратной косой чертой и новой строкой, но эта практика требует, чтобы продолжение строки начиналось с первой позиции следующей строки. Чтобы обеспечить более гибкую компоновку и решить некоторые проблемы предварительной обработки (см. §3.8.3), Комитет ввел конкатенацию строковых литералов. Два строковых литерала в строке вставляются вместе (без нулевого символа в середине), чтобы получился один комбинированный строковый литерал. Это дополнение к языку C позволяет программист, чтобы расширить строковый литерал за пределы конца физической строки без необходимости использовать механизм обратной косой черты и новой строки и тем самым разрушить схему отступов программы. Явный оператор конкатенации не был введен, потому что конкатенация является лексической конструкцией, а не запуском время работы."
  18. ^ Обоснование языка программирования ANSI C . Silicon Press. 1990. стр. 6566 . ISBN 0-929306-07-4., 3.8.3.2 Оператор # : "Оператор # был введен для преобразования в строку. Его можно использовать только в раскрытии #define. Он вызывает замену следующего за ним имени формального параметра строковым литералом, сформированным путем преобразования в строку фактического токена аргумента. Последовательность. В сочетании с конкатенацией строковых литералов (см. §3.1.4), использование этого оператора позволяет создавать строки так же эффективно, как путем замены идентификатора внутри строки. Пример в Стандарте иллюстрирует эту особенность ».
  19. ^ Журнал пользователей C / C ++, том 19, стр. 50
  20. ^ "Python - Почему разрешено объединение строковых литералов?" . Переполнение стека . Проверено 22 июня 2016 .
  21. ^ "LINE__ в строку (преобразование в строку) с использованием директив препроцессора" . Decompile.com . 2006-10-12 . Проверено 22 июня 2016 .
  22. ^ Справочник по языку Python, 2. Лексический анализ, 2.4.2. Конкатенация строковых литералов : "Эта функция может использоваться для уменьшения количества необходимых обратных косых черт, для удобного разделения длинных строк на длинные строки или даже для добавления комментариев к частям строк, например:
  23. ^ Система отслеживания проблем DLang - Проблема 3827 - Предупредить и затем отказаться от неявной конкатенации смежных строковых литералов
  24. ^ Проект стандарта C ++ 11 , «Рабочий проект стандарта языка программирования C ++» (PDF) . , 2.14.5 Строковые литералы [lex.string], примечание 13, с. 28–29: «Любые другие конкатенации условно поддерживаются с поведением, определяемым реализацией».
  25. ^ "Архивная копия" . Архивировано из оригинального 14 июля 2014 года . Проверено 3 июля 2014 года .CS1 maint: заархивированная копия как заголовок ( ссылка )
  26. ^ «2. Лексический анализ - документация Python 2.7.12rc1» . python.org . Проверено 22 июня +2016 .
  27. ^ "perlop - perldoc.perl.org" . perl.org . Проверено 22 июня +2016 .

Внешние ссылки [ править ]

  • Литералы в программировании