C.W.K.
Stream
Lesson 08 of 12 · published

Escaping Special Characters — When and How

~8 min · escaping, metacharacters, raw-strings

Level 0Pattern-Curious
0 XP0/90 lessons0/15 achievements
0/100 XP to next level100 XP to go0% complete

Backslash makes special literal, and vice versa

Two facts:

  1. To match a metacharacter literally, put a backslash in front: \. matches a dot, \$ matches a dollar sign, \\ matches a backslash.
  2. To create a special meaning out of an ordinary letter, put a backslash in front: \d means digit, \b means word boundary, \n means newline.

The backslash is the universal mode flip.

Raw strings save your sanity

In Python, JavaScript template literals, and most languages, the backslash is ALSO the string-escape character. So "\d" in a Python string is interpreted by the string parser before regex sees it — sometimes harmlessly, sometimes catastrophically.

Always use raw strings (or the equivalent) for regex patterns. Python: r"\d+". Rust: r"\d+". JavaScript regex literals: /\d+/ (the slashes provide the same protection).

Without raw strings: "\d" in Python is the same as "\\d" by accident, but "\b" is the ASCII bell character (8) — your pattern is silently wrong.

Programmatic escaping

If you're building a regex from user input or a variable, use the escape function: Python re.escape(), JavaScript needs a polyfill (no built-in), Go regexp.QuoteMeta(). Never concatenate raw user input into a pattern.

Code

Escaping done right·python
import re

# Match a literal $19.99
re.findall(r'\$\d+\.\d{2}', 'price was $19.99 today')
# ['$19.99']

# WITHOUT raw string — silently wrong
import re
pattern = "\d+"  # Python sees: "\d+" → backslash interpreted by str
print(repr(pattern))  # '\\d+' actually  (depends on version)

# Programmatic escaping for user input
user_input = 'price: $19.99'
safe = re.escape(user_input)
print(safe)
# 'price:\\ \\$19\\.99'
re.findall(safe, 'note: price: $19.99 today')

External links

Exercise

Build a regex that matches a URL like https://example.com/path?query=1 *literally* — escape every special character correctly. Then use re.escape() on the same URL string and compare your hand-written escape to what the function produced.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.