Экранирование зависит от контекста
Строка никогда не бывает «экранированной» абстрактно; она экранируется для одного конкретного места, куда её собираются вставить, и у каждого места свои правила. Один и тот же текст требует \" в JSON, '' в SQL, '\'' в shell и " в HTML. Использование не того варианта — источник инъекций: HTML-экранирование перед вставкой текста в строку JavaScript или экранирование для shell двойными кавычками с оставленным активным $.
| Контекст | Что нужно экранировать | Как |
|---|---|---|
| Строка JSON | " \ и управляющие символы | \" \\ \n \t \u00XX |
| Shell, одинарные кавычки | ' | '\'' (закрыть, буквальная кавычка, открыть снова) |
| Shell, двойные кавычки | " \ $ ` и ! в интерактивном bash | обратная косая черта |
| SQL-литерал | ' | '' (MySQL также принимает \') |
| Regex | . * + ? ^ $ { } ( ) [ ] | \ / | обратная косая черта |
| C / Go / Rust / Java | " \ перевод строки табуляция | \" \\ \n \t \xHH \uHHHH |
| Поле CSV | , " перевод строки | заключить в кавычки, удвоить кавычки |
| Текст HTML / XML | & < > " ' | & < > " ' / ' |
| YAML | Всё неоднозначное: yes, no, 1.0, ведущие * или &, двоеточия | Двойные кавычки с JSON-экранированием |
Shell в частности
Одинарные кавычки — единственный полностью безопасный способ квотирования в POSIX shell: ничего внутри не интерпретируется, и единственный символ, который не может там появиться, — сама одинарная кавычка; её записывают, завершая строку, добавляя экранированную кавычку и начиная заново: 'it'\''s'. Двойные кавычки по-прежнему раскрывают $переменные, `команды` и \, так что они нужны, когда вы хотите подстановку. Передавая данные из кода, вообще не собирайте командные строки: используйте массив аргументов (execve, subprocess.run([...]), exec.Command), и экранирование станет ненужным.
SQL в частности
Удвоение кавычек — корректный SQL, но не так приложения должны передавать значения. Параметризованные запросы ($1, ?, :name) отправляют значение отдельно от выражения и делают инъекцию невозможной. Используйте SQL-экранирование для разовых запросов в консоли, а не в коде.
Вопросы
Как вставить одинарную кавычку в строку shell в одинарных кавычках?
Завершите строку, добавьте экранированную кавычку, начните снова: 'it'\''s'. Или используйте $'it\'s' в bash/zsh, где поддерживаются escape-последовательности с обратной косой чертой.
Почему в моём JSON \u00e9 вместо é?
Некоторые кодировщики экранируют все не-ASCII символы для безопасности в 7-битных каналах. Это по-прежнему валидно и декодируется в ту же строку. JSON.stringify в JavaScript и json.dumps с ensure_ascii=False в Python сохраняют символы.
В чём разница между экранированием и кодированием?
Экранирование защищает несколько специальных символов, чтобы текст мог находиться внутри синтаксиса; кодирование (Base64, URL) преобразует всю строку в другой алфавит. Base64 и URL-кодирование включены сюда, потому что часто нужны в том же контексте.
Можно ли экранировать для regex конкретного языка?
Экранирование regex охватывает метасимволы, общие для всех распространённых движков (PCRE, JavaScript, Python, Go RE2, Java). Внутри символьного класса [] значимы только ] \ ^ и -; инструмент экранирует консервативно, чтобы результат работал везде.