Как вывести кавычки в java
Перейти к содержимому

Как вывести кавычки в java

  • автор:

Как вставить символ двойных кавычек в строку?

Самый стандартный способ, применяемый во многих языка, в том числе и в Java — экранирование с помощью символа \ :

String myString = "Строка со \"словом\" в кавычках"; 

Отслеживать
28.8k 12 12 золотых знаков 59 59 серебряных знаков 118 118 бронзовых знаков
ответ дан 2 апр 2015 в 8:24
DreamChild DreamChild
36.2k 3 3 золотых знака 45 45 серебряных знаков 85 85 бронзовых знаков
Это еще называется escape символ
2 апр 2015 в 8:47

Благодарю, это работает, но задача усложнилась.Перед кавычками еще надо поставить слеш +»
2 апр 2015 в 9:13
решается аналогично
2 апр 2015 в 9:16
Да, действительно
2 апр 2015 в 9:17
в конце строки кавычки лишние
13 дек 2016 в 15:06

String str1 = "Строка со \"словом\" в кавычках"; 

Отслеживать
ответ дан 2 апр 2015 в 8:23
Павел Вершинин Павел Вершинин
3,981 1 1 золотой знак 15 15 серебряных знаков 23 23 бронзовых знака

Да, есть, добавляешь перед каждым символом который нужно экранировать \ . Например, для вывода на экран «C: \\\folder\\\folder1\» нужно добавить по «экрану» перед КАЖДЫМ символом вот так:

System.out.println("\"C: \\\\\\\folder\\\\\\\folder1\\\\\""); 

Отслеживать
9,333 3 3 золотых знака 29 29 серебряных знаков 57 57 бронзовых знаков
ответ дан 31 мар 2017 в 9:26
21 1 1 бронзовый знак

final char dm = (char) 34; final String string = "STRING: " + dm + " string " + dm; System.out.println(string); 

Отслеживать
ответ дан 12 ноя 2017 в 7:49
4,106 4 4 золотых знака 13 13 серебряных знаков 29 29 бронзовых знаков
Вообще не понял, а за что заминусовали? У меня всё отработало прекрасно.
20 дек 2018 в 15:24

 String x = "\\"; String y = "\""; System.out.println("It's Windows path: " + y + "C:" + x + "Program Files" + x + "Java" + x + "jdk1.7.0" + x + "bin" + y); System.out.println("It's Java string: " + x + y + "C:" + x + x + "Program Files" + x + x + "Java" + x + x + "jdk1.7.0" + x + x + "bin" + x + y); 

Отслеживать
ответ дан 24 янв 2016 в 21:12
11 1 1 бронзовый знак
Решение задачи с JavaRush, верно? А есть «нормальный» способ экранировать кавычки?
26 окт 2016 в 17:46
@Dunaevsky Maxim, А символом для экранирования экранировать не нормально? 🙂
29 июн 2017 в 14:06

  • java
  • android
  • строки
    Важное на Мете
Похожие

Подписаться на ленту

Лента вопроса

Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.

Дизайн сайта / логотип © 2024 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2024.1.17.3574

Как экранировать кавычки внутри кавычек?

Всем привет!
Выполняю парсин данных из инстаграм на Java. Json, который возвращает instagram, является невалидным, т.к. иногда в некоторых полях с именованием внутри кавычек присутствуют ещё кавычки, которые не экранируются, например:
«full_name»: «Агроусадьба «Марусина Хата «»,
Должно быть:
«full_name»: «Агроусадьба \»Марусина Хата\»»,

Может кто-нибудь сталкивался, как можно экранировать кавычки внутри кавычек, используя регулярное выражение?

  • Вопрос задан более года назад
  • 982 просмотра

3 комментария

Простой 3 комментария

Как вывести кавычки в java

В данной статье архитектор Java Brian Goetz подробно рассказывает о появившейся в Java новой фиче языка — текстовые блоки.

В Java SE 13 текстовые блоки были представлены в качестве предварительной функции языка. Целью их создания стало желание разработчиков уменьшить трудности объявления и использования многострочных строковых литералов в Java.

Впоследствии текстовые блоки были усовершенствованы во втором предварительном релизе с небольшими изменениями и должны стать постоянной функцией языка в Java SE 15 (сентябрь 2020 г.).

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

 String address = """ 25 Main Street Anytown, USA, 12345 """; 

В этом простом примере переменная address будет содержать двухстрочную строку с разделителями после каждой строки.

До появления текстовых блоков Java-программисты писали строковые литералы так:

 String address = "25 Main Street\n" + "Anytown, USA, 12345\n"; или String address = "25 Main Street\nAnytown, USA, 12345\n"; 

Каждый Java-разработчик знает, как громоздко могут выглядеть подобные строковые литералы. Кроме этого такой код более подвержен ошибкам (легко забыть поставить \n) и труден для чтения (синтаксис языка смешивается с содержимым строки). Поскольку в текстовом блоке обычно отсутствуют escape-символы и другие лингвистические помехи, то это позволяет языку «не путаться под ногами», а также повышает читаемость содержимого строки.

Наиболее часто используемым экранирующим символом в строковых литералах является символ новой строки (\n), который больше не требуется в текстовых блоках. Следующим по популярности идет символ двойная кавычка («), которую необходимо экранировать, поскольку она конфликтует с кавычками, обрамляющими строковый литерал. Текстовые блоки также устраняют необходимость в ней, т.к. одиночная кавычка не конфликтует с ограничителем текстового блока в виде тройных кавычек.

1. Почему было выбрано такое забавное название?

Кто-то мог бы подумать, что эту функцию языка нужно было бы назвать «многострочный строковый литерал» (и, возможно, именно так ее будут называть многие люди). Но мы выбрали другое имя, текстовые блоки, чтобы подчеркнуть тот факт, что текстовый блок — это не просто несвязанный набор строк, а скорее двумерный блок текста, встроенный в программу Java.

Чтобы проиллюстрировать, что мы подразумеваем под «двумерным», давайте возьмем немного более структурированный пример, представляющий собой фрагмент XML (те же соображения применимы и к строкам на каком-то другом «языке», таком как SQL, HTML, JSON или даже Java, которые встраиваются как литералы в программу):

 void m() < System.out.println(""" Bob Jones  """); > 

Что же автор этих строк ожидает увидеть напечатанным? Несмотря на то, что мы не можем читать его мысли, кажется маловероятным, что цель состояла в том, чтобы XML-код имел отступ в 23 пробела. Гораздо более вероятно, что эти 23 пробела существует исключительно для выравнивания текстового блока относительно другого кода. С другой стороны, автор почти наверняка предполагал, что вторая строка XML-кода должна иметь отступ на четыре пробела больше, чем первая. Кроме того, даже если ему действительно нужно ровно 23 пробела, то что произойдет, если программа изменится? Мы не хотим, чтобы отступ при выводе изменялся только потому, что исходный код был переформатирован.

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

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

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

Аналогия с «магическим прямоугольником» может помочь в понимании того, как работают текстовые блоки. При этом следует добавить, что баланс побочных и основных отступов можно регулировать, используя положение закрывающего разделителя («»») относительно строкового литерала.

2. Детали

В текстовом блоке в качестве открывающего и закрывающего разделителя используются тройные кавычки («»»). Содержимое текстового блока должно начинаться с новой строки, а не на строке, где находится открывающий разделитель и продолжаться до закрывающего разделителя:

 // Ошибка String name = """Pat Q. Smith"""; // Ошибка String name = """red green blue """; // OK String name = """ red green blue """; 

Обработка содержимого блока во время компиляции имеет три фазы:

  • Нормализация ограничителей строки. Все разделители строк заменяются принудительно символом LF (\u000A). Это предотвращает внесение изменений, принятых в той или иной операционной системе (windows использует CR + LF для завершения строк, в то время как системы Unix используют только LF. Могут использоваться и другие схемы)

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

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

 void m() < System.out.println(""" Bob Jones  """); > 

Поскольку последняя строка также является определяющей, то общий пробельный префикс теперь считается от начала закрывающего разделителя. Все пробелы перед ним — удаляются из каждой строки. В итоге остается общий отступ для всего блока в четыре пробела. Мы также можем управлять отступами программно, с помощью метода String:indent, который принимает многострочную строку и выравнивает в ней каждую строчку на фиксированное количество пробелов:

 void m() < System.out.println(""" Bob Jones  """.indent(4)); > 

3. Встроенные выражения

В Java строковые литералы (и текстовые блоки) не поддерживают интерполяцию выражений (подстановку переменных), как некоторые другие языки. Исторически строковые выражения создавались с помощью обычной конкатенации строк (+). В Java 5 был добавлен String:format для форматирования строк в стиле «printf».

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

 String person = """ %s %s  """.formatted(first, last)); 

(К сожалению, этот метод также нельзя назвать форматным, поскольку мы не можем перегрузить статические методы и методы экземпляров с одинаковыми именами и списками параметров.

4. Прецеденты и история

Хотя строковые литералы, в некотором смысле, являются «тривиальной» функцией, они используются достаточно часто, тем самым накапливая небольшие раздражения. Поэтому неудивительно, что отсутствие многострочных строк было одной из самых распространенных жалоб на Java в последние годы. Кроме того, многие другие языки имеют несколько видов строковых литералов для различных вариантов использования.

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

В следующей таблице показаны (некоторые из) вариантов строковых литералов в разных языках. В каждом случае ‘…’ считается содержимым строкового литерала, в котором поддерживаются или не поддерживаются escape-последовательности и интерполяции. ‘xxx‘ представляет выбранный пользователем одноразовый номер, который гарантированно не конфликтует с содержимым строки. ‘##‘ представляет переменное количество символов ‘#’ (которое может быть нулевым).

Language;Syntax;Notes
Условные обозначения:

  • esc — некоторая степень обработки escape-последовательности, где escape-символы обычно взяты из стиля языка C (например, \n)
  • Interp — некоторая поддержка интерполяции переменных или произвольных выражений
  • span — многострочные строки могут быть выражены простым соединением нескольких исходных строк
  • here — «here-doc» (синтаксис занесения в переменную одно- или (часто) многострочного свободно форматированного текста «как есть»), где последующие строки, вплоть до строки, которая содержит только выбранный пользователем одноразовый номер, обрабатываются как тело строкового литерала
  • prefix — форма префикса действительна для всех других форм строковых литералов и для краткости опущена
  • delim — разделитель можно настраивать в некоторой степени, будь то путем включения однократно используемого номера (C++), различного количества символов # (Rust, Swift) или замены фигурных скобок для других совпадающих скобок (Ruby)
  • strip — некоторая степень поддержки удаления случайных отступов

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

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

Неудивительно, что скриптовые языки (bash, Perl, Ruby, Python) сделали «выбор пользователя» своим первым приоритетом для литералов, которые могут различаться разными способами выражения одного и того же. Но в целом, языки совершенно не волнует, как они побуждают пользователей думать о строковых литералах, сколько форм они используют и насколько ортогональны эти формы.

Мы также видим несколько подходов к строкам, состоящим из нескольких строк. Некоторые (например, Javascript и Go) обрабатывают окончания строк, как просто еще один символ, позволяющий всем формам строковых литералов занимать несколько строк. Одни (например, C++) рассматривают их как особый случай «сырых» строк, другие (например, Kotlin) делят строки на «простые» и «сложные». а третьи предлагают так много вариантов, что они не поддаются даже этим простым классификациям. Точно так же они различаются в своей интерпретации «необработанной строки» и т. д.

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

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

5. Дорога почти взята

Текстовые блоки не были первой попыткой реализации этой функции — первой итерацией были необработанные строковые литералы. Как и необработанные строки Rust, они использовали разделитель переменного размера (любое количество символов кавычек) и вообще не интерпретировали содержимое. Это предложение было отозвано после того, как оно было полностью спроектировано и прототипировано, т.к. чувствовалось, что оно слишком «прибито сбоку». У него было слишком мало общего с традиционными строковыми литералами, и, следовательно, если бы мы хотели расширить его возможности в будущем, у нас бы ничего не вышло.

Одним из основных возражений против подхода JEP 326 является то, что необработанные строки работали во всех отношениях иначе, чем традиционные строковые литералы: различные символы-разделители, отличающиеся от фиксированных разделителей; одиночные-многострочные; экранирующие и не экранирующие. Как обычно, кто-то захочет получить какую-то другую комбинацию выбора и будут призывы к другим формам, ведущие нас по пути, который выбрал Bash. Кроме того, он ничего не сделал для решения проблемы «случайного отступа», которая, очевидно, станет источником хрупкости в программах Java. Основываясь на этом опыте, текстовые блоки имеют гораздо больше общего с традиционными строковыми литералами (синтаксис разделителя, escape-язык). Различия только в одном важном аспекте — является ли строка одномерной последовательностью символов или двумерным текстовым блоком.

Как вывести кавычки в java

Создайте регулярное выражение для поиска строк в двойных кавычках «. » .

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

let str = "Как вот \"здесь\".";

В частности, обратите внимание: двойная кавычка после обратного слеша \» не оканчивает строку.

Поэтому мы должны искать от одной кавычки до другой, игнорируя встречающиеся экранированные кавычки.

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

Примеры подходящих строк:

.. "test me" .. .. "Скажи \"Привет\"!" . (строка с экранированными кавычками) .. "\\" .. (внутри двойной слеш) .. "\\ \"" .. (внутри двойной слеш и экранированная кавычка)

В JavaScript приходится удваивать обратные слеши, чтобы добавлять их в строку, как здесь:

let str = ' .. "test me" .. "Скажи \\"Привет\\"!" .. "\\\\ \\"" .. '; // эта строка в памяти: alert(str); // .. "test me" .. "Скажи \"Привет\"!" .. "\\ \"" ..
  • Сначала ищем открывающую кавычку «
  • Затем, если есть обратный слеш \\ (удвоение обратного слеша – техническое, потому что это спец.символ, на самом деле там один обратный слеш), то после него также подойдёт любой символ (точка).
  • Иначе берём любой символ, кроме кавычек (которые будут означать конец строки) и обратного слеша (чтобы предотвратить одинокие обратные слеши, сам по себе единственный обратный слеш не нужен, он должен экранировать какой-то символ) [^»\\]
  • …И так далее, до закрывающей кавычки.
let regexp = /"(\\.|[^"\\])*"/g; let str = ' .. "test me" .. "Скажи \\"Привет\\"!" .. "\\\\ \\"" .. '; alert( str.match(regexp) ); // "test me","Скажи \"Привет\"!","\\ \""

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *