Как вернуть специальные символы в экранированный url
Перейти к содержимому

Как вернуть специальные символы в экранированный url

  • автор:

Как экранировать спецсимволы, например » \?», в строке URL из Java

Есть строка, содержащая знак вопроса ? , или несколько. Строка передается как параметр в URL. Знак вопроса нужно заменить на %3f . Как это сделать?

String text = text.replaceAll("\?", "%3f"); 

Такой код дает ошибку:

Dangling meta character '?' near index 0 

Перевод вопроса с enSO: «Replace a question mark (?) with (\?)», не дословный, но очень похоже.
Отслеживать
задан 29 сен 2017 в 17:27
user236980 user236980

3 ответа 3

Сортировка: Сброс на вариант по умолчанию

Разобрался сам. Поскольку знак вопроса «?» является спецсимволом в regexp, то экранировать его нужно не одним «\» слешем, а двумя «\\»

String text = text.replaceAll("\\?", "%3f"); 

Ну а в общем случае для разных спецсимволов у меня получилось вот что:

String text = text .replaceAll("%", "%25") // Процент .replaceAll(" ", "%20") // Пробел .replaceAll("\t", "%20") // Табуляция (заменяем на пробел) .replaceAll("\n", "%20") // Переход строки (заменяем на пробел) .replaceAll("\r", "%20") // Возврат каретки (заменяем на пробел) .replaceAll("!", "%21") // Восклицательный знак .replaceAll("\"", "%22") // Двойная кавычка .replaceAll("#", "%23") // Октоторп, решетка .replaceAll("\\$", "%24") // Знак доллара .replaceAll("&", "%26") // Амперсанд .replaceAll("'", "%27") // Одиночная кавычка .replaceAll("\\(", "%28") // Открывающаяся скобка .replaceAll("\\)", "%29") // Закрывающаяся скобка .replaceAll("\\*", "%2a") // Звездочка .replaceAll("\\+", "%2b") // Знак плюс .replaceAll(",", "%2c") // Запятая .replaceAll("-", "%2d") // Дефис .replaceAll("\\.", "%2e") // Точка .replaceAll("/", "%2f") // Слеш, косая черта .replaceAll(":", "%3a") // Двоеточие .replaceAll(";", "%3b") // Точка с запятой .replaceAll("", "%3e") // Закрывающаяся угловая скобка .replaceAll("\\?", "%3f") // Вопросительный знак .replaceAll("@", "%40") // At sign, по цене, собачка .replaceAll("\\[", "%5b") // Открывающаяся квадратная скобка .replaceAll("\\\\", "%5c") // Одиночный обратный слеш '\' .replaceAll("\\]", "%5d") // Закрывающаяся квадратная скобка .replaceAll("\\^", "%5e") // Циркумфлекс .replaceAll("_", "%5f") // Нижнее подчеркивание .replaceAll("`", "%60") // Гравис .replaceAll("\\", "%7d") // Закрывающаяся фигурная скобка .replaceAll("~", "%7e"); // Тильда 

Экранирование, специальные символы

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

Есть и другие специальные символы, которые имеют особое значение в регулярном выражении. Они используются для более сложных поисковых конструкций. Вот полный перечень этих символов: [ ] \ ^ $ . | ? * + ( ) .

Не надо пытаться запомнить этот список: мы разберёмся с каждым из них по отдельности, и таким образом вы выучите их «автоматически».

Экранирование символов

Допустим, мы хотим найти буквально точку. Не «любой символ», а именно точку.

Чтобы использовать специальный символ как обычный, добавьте к нему обратную косую черту: \. .

Это называется «экранирование символа».

alert( "Глава 5.1".match(/\d\.\d/) ); // 5.1 (совпадение!) alert( "Глава 511".match(/\d\.\d/) ); // null ("\." - ищет обычную точку)

Круглые скобки также являются специальными символами, поэтому, если нам нужно использовать именно их, нужно указать \( . В приведённом ниже примере ищется строка «g()» :

alert( "function g()".match(/g\(\)/) ); // "g()"

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

alert( "1\\2".match(/\\/) ); // '\'

Косая черта

Символ косой черты ‘/’ , так называемый «слэш», не является специальным символом, но в JavaScript он используется для открытия и закрытия регулярного выражения: /. шаблон. / , поэтому мы должны экранировать его.

Вот как выглядит поиск самой косой черты ‘/’ :

alert( "/".match(/\//) ); // '/'

С другой стороны, если мы не используем короткую запись /. / , а создаём регулярное выражение, используя new RegExp , тогда нам не нужно экранировать косую черту:

alert( "/".match(new RegExp("/")) ); // находит /

new RegExp

Если мы создаём регулярное выражение с помощью new RegExp , то нам не нужно учитывать / , но нужно другое экранирование.

Например, такой поиск не работает:

let regexp = new RegExp("\d\.\d"); alert( "Глава 5.1".match(regexp) ); // null

Аналогичный поиск в примере выше с /\d\.\d/ вполне работал, почему же не работает new RegExp(«\d\.\d») ?

Причина в том, что символы обратной косой черты «съедаются» строкой. Как вы помните, обычные строки имеют свои специальные символы, такие как \n , и для экранирования используется обратная косая черта.

Вот как воспринимается строка «\d.\d»:

alert("\d\.\d"); // d.d

Строковые кавычки «съедают» символы обратной косой черты для себя, например:

  • \n – становится символом перевода строки,
  • \u1234 – становится символом Юникода с указанным номером,
  • …А когда нет особого значения: как например для \d или \z , обратная косая черта просто удаляется.

Таким образом, new RegExp получает строку без обратной косой черты. Вот почему поиск не работает!

Чтобы исправить это, нам нужно удвоить обратную косую черту, потому что строковые кавычки превращают \\ в \ :

let regStr = "\\d\\.\\d"; alert(regStr); // \d\.\d (теперь правильно) let regexp = new RegExp(regStr); alert( "Глава 5.1".match(regexp) ); // 5.1

Итого

  • Для поиска специальных символов [ ] \ ^ $ . | ? * + ( ) , нам нужно добавить перед ними \ («экранировать их»).
  • Нам также нужно экранировать / , если мы используем /. / (но не new RegExp ).
  • При передаче строки в new RegExp нужно удваивать обратную косую черту: \\ для экранирования специальных символов, потому что строковые кавычки «съедят» одну черту.

URL кодирование и декодирование строк

MENU

Кодирование URL и просто двоичных данных в последовательность букв, цифр и некоторых специальных знаков латинского алфавита в интернете было связано с ограничением физических устройств на передачу только алфавитно-цифровых символов. В URL такое кодирование обычно применяется для передачи символов в формате Unicode (как правило UTF-8) в последовательность из двух байт, записанных в шестнадцатиричном представлении. Каждый байт предваряется знаком %. При таком кодировании строчка «корова» будет иметь вид: %D0%BA%D0%BE%D1%80%D0%BE%D0%B2%D0%B0 . То есть русской букве к будет соответствовать последовательность %D0%BA и.т.д. Такое кодирование является общепринятым для путей к файлам или папкам, входящим в URL.

Подмножесто символов, которые разрешены в URL немного шире чем алфавитно-цифровые символы, так, в URL можно использовать дефис и подчеркивание, но нельзя, например, использовать одинарные или двойные кавычки. Некоторые символы используют для разделения параметров в URL, и их кодирование в этом случае будет неправомочным. В зависимости от отношения к кодированию специальных символов в javascript различают функции encodeURI и decodeURI, которые могут работать с полным URL, и, функции encodeURIComponent / decodeURIComponent, применяемые для параметров, входящих в URL.

Вообще говоря, кодирование параметров может быть достаточно произвольным. Здесь разработчик может использовать любую схему кодировки, если состав ее символов будет коректно передаваться через сеть. Так, вместо строки кириллицы в utf-8 можно применить строку в кодировке Windows 1251. В этом случае слово «корова» будет выглядеть как %EA%EE%F0%EE%E2%E0. То есть, символу к будет соответствовать последовательность из двух букв со знаком процента перед ними — %EA. Закодировать в строки с процентами кириллицу из других кодировок можно в нашем HTML кодировщике. В принципе, допустимы также другие способы кодирования, например, escape/unescape функцию javascript. Слово «корова» в этом случае будет выглядеть как %u043A%u043E%u0440%u043E%u0432%u0430 .

Как в requests передать url без экранирования спец символов?

domen.com/banana-100%25-fruit-4x90g’
Библиотека requests по get запросу выдает ошибку 400. Как сделать запрос через requests не экранирую %25?

  • Вопрос задан более трёх лет назад
  • 1327 просмотров

Комментировать

Решения вопроса 0

Ответы на вопрос 1

dimonchik2013

Dimonchik @dimonchik2013

non progredi est regredi

Ответ написан более трёх лет назад

dim137

Дмитрий Вяткин @dim137 Автор вопроса

Мне надо что бы %25 остался в урле, а не превращался в %

Ваш ответ на вопрос

Войдите, чтобы написать ответ

python

  • Python

Python какой хостинг подойдет, и в чем проблема?

  • 1 подписчик
  • час назад
  • 10 просмотров

python

  • Python
  • +1 ещё

Как создать хэндлер Aiogram 3.4 для обработки ошибки на Python?

  • 1 подписчик
  • 4 часа назад
  • 14 просмотров

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

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