Reference library

Character escaping: HTML, URL, JSON, JavaScript, RegExp, and Markdown

A comparison of escaping rules for HTML, URL components, JSON strings, JavaScript, regular expressions, and Markdown with copy-ready values.

24 rows
Contexts6HTML · URL · JSON · JS · RegExp · MD
Compared rows24characters and fragments
Main ruleescape at the parser boundary
Quick comparison

The same character in six contexts

The columns use the assumptions described below. Select any value to copy it exactly; SP, LF, and TAB are visible labels for whitespace.

Character escaping comparison for HTML, URL, JSON, JavaScript, RegExp, and Markdown
Character HTMLURLJSONJavaScriptRegExpMarkdown
& Ampersand
< Less-than sign
> Greater-than sign
" Double quotation mark
' Apostrophe
` Backtick
SP Space
/ Slash
\ Backslash
# Number sign
? Question mark
= Equals sign
% Percent sign
. Full stop
^ Caret
$ Dollar sign
| Vertical line
* Asterisk
+ Plus sign
() Parentheses
[] Square brackets
{} Curly braces
LF Line feed
TAB Tab
Scope first

What each column means

Escaping is correct only relative to the parser that will read the result.

HTMLText and attribute values

Replace &, <, >, and quotes with character references. For text, assigning textContent is safer than assembling markup as strings.

Input<span title="A&B"> Result
Watch for: Rules differ for text, attributes, URLs inside attributes, and <script> contents.
URLOne URL component

Encode data with encodeURIComponent or URLSearchParams. Do not encode an entire URL as one component.

Inputa+b & c/d Result
Watch for: encodeURIComponent leaves apostrophe, !, *, (, and ) unchanged; strict RFC 3986 handling sometimes encodes them additionally.
JSONJSON string contents

Escape the quotation mark, backslash, and control characters. In practice, use JSON.stringify.

InputHe said "hi" + LF Result
Watch for: JSON is a data format, not a JavaScript fragment: comments, single quotes, and trailing commas are not standard JSON.
JavaScriptA double-quoted string

Escape the double quote, backslash, and control characters. Template literals have separate rules for ` and ${…}.

InputC:\temp\new Result
Watch for: Do not interpolate untrusted data into code. Pass it as data or serialize it for the actual boundary.
RegExpRegular-expression literal body

Prefix ^ $ \ . * + ? ( ) [ ] { } | with a backslash, and escape / inside a /…/ literal.

Inputprice: 10.00? Result
Watch for: In a string passed to the RegExp constructor, the backslash must be escaped again at the JavaScript-string level.
MarkdownCommonMark plain text

Prefix ASCII punctuation with a backslash only when the character could otherwise become markup.

Input*literal* [text] Result
Watch for: Rules depend on position: #, +, -, >, and a dot after a digit are especially important at the start of a line.
Safe boundaries

Three questions before escaping

  1. 1

    Where will the value be inserted?

    HTML text, an HTML attribute, a URL query value, a JavaScript string, and a RegExp pattern are different parsing contexts.

  2. 2

    Which layer parses it first?

    A pattern passed through a JSON document and then into RegExp may need serialization at each boundary, but never a blind double-escape.

  3. 3

    Can a serializer do the work?

    Prefer textContent, URLSearchParams, JSON.stringify, and data APIs. Hand-written replacement chains are easy to apply in the wrong order.

Specifications

HTML, URL, JSON, JavaScript, RegExp and CommonMark.

Related tools

Continue working with text

Copy a symbol, convert markup, clean a fragment, or keep the result in the notebook.

FAQ

Questions about character escaping

Is escaping the same as encoding?

Not exactly. Escaping protects syntax inside a specific grammar; encoding maps data into another representation. URL percent-encoding and HTML character references are commonly discussed alongside escaping because they solve the same boundary problem.

Why should a value not be escaped twice?

The second pass usually escapes the first pass itself: & becomes &amp;amp; or % becomes %25. Serialize once for each real parser boundary and keep the original value internally.

Should I escape HTML with a regular expression?

No. Put plain text into textContent, use DOM APIs for attributes, or use the context-aware escaping built into a trusted template engine.

Why is / escaped in a RegExp literal but not always in RegExp()?

In /pattern/, a slash closes the literal, so it must be written as /. In new RegExp(pattern), the pattern is supplied as a JavaScript string and the slash is not a delimiter, but string-level backslashes still matter.

Does every Markdown punctuation mark need a backslash?

No. CommonMark permits backslash escapes for ASCII punctuation, but use them only where a character would otherwise start markup. Position changes the meaning of #, +, -, >, and numbered-list dots.