159

Does Python have a function that I can use to escape special characters in a string?

For example, I'm "stuck" :\ should become I\'m \"stuck\" :\\.

poke
  • 369,085
  • 72
  • 557
  • 602
Wolfy
  • 4,213
  • 8
  • 35
  • 42
  • 4
    What do you consider to be a special character? – pafcu Nov 17 '10 at 08:10
  • 2
    Completely depends on your context. Usually those characters are totally fine when you have them inside a string. – poke Nov 17 '10 at 08:16
  • possible duplicate of [Escaping regex string in Python](http://stackoverflow.com/questions/280435/escaping-regex-string-in-python) – Jukka Suomela Dec 18 '13 at 19:48
  • 2
    The question originally did not say anything about regular expressions but this was only added in an edit three years later. Since we already have a good canonical for escaping regex strings, I have reverted the question to its original meaning since the majority of answers are also not in response to this special case. – poke Aug 07 '21 at 21:37
  • @poke as you noted at the time, the question is not answerable as asked, because neither "escape" nor "special" is properly defined. For example, should a newline be left alone? Have a backslash inserted before it? Turned into a backslash followed by lowercase n? Turned into a backslash followed by lowercase x followed by zero followed by lowercase a? Something else? – Karl Knechtel Aug 05 '22 at 01:34
  • Related: [`unicode-escape`](https://stackoverflow.com/a/9339658/5267751), [`shlex.quote`](https://stackoverflow.com/q/35817/5267751). – user202729 Dec 23 '22 at 08:42

7 Answers7

255

Use re.escape

>>> import re
>>> re.escape(r'\ a.*$')
'\\\\\\ a\\.\\*\\$'
>>> print(re.escape(r'\ a.*$'))
\\\ a\.\*\$
>>> re.escape('www.stackoverflow.com')
'www\\.stackoverflow\\.com'
>>> print(re.escape('www.stackoverflow.com'))
www\.stackoverflow\.com

Repeating it here:

re.escape(string)

Return string with all non-alphanumerics backslashed; this is useful if you want to match an arbitrary literal string that may have regular expression metacharacters in it.

As of Python 3.7 re.escape() was changed to escape only characters which are meaningful to regex operations.

Community
  • 1
  • 1
pyfunc
  • 65,343
  • 15
  • 148
  • 136
  • 2
    You may use regex module instead of re. An example would be `regex.escape(pattern,string,special_only=True` – Lokinou Nov 05 '18 at 09:29
  • Note that `re.escape` will turn e.g. a newline into a backslash followed by a newline; one might well instead want a backslash followed by a lowercase n. – Karl Knechtel Aug 05 '22 at 01:32
23

I'm surprised no one has mentioned using regular expressions via re.sub():

import re
print re.sub(r'([\"])',    r'\\\1', 'it\'s "this"')  # it's \"this\"
print re.sub(r"([\'])",    r'\\\1', 'it\'s "this"')  # it\'s "this"
print re.sub(r'([\" \'])', r'\\\1', 'it\'s "this"')  # it\'s\ \"this\"

Important things to note:

  • In the search pattern, include \ as well as the character(s) you're looking for. You're going to be using \ to escape your characters, so you need to escape that as well.
  • Put parentheses around the search pattern, e.g. ([\"]), so that the substitution pattern can use the found character when it adds \ in front of it. (That's what \1 does: uses the value of the first parenthesized group.)
  • The r in front of r'([\"])' means it's a raw string. Raw strings use different rules for escaping backslashes. To write ([\"]) as a plain string, you'd need to double all the backslashes and write '([\\"])'. Raw strings are friendlier when you're writing regular expressions.
  • In the substitution pattern, you need to escape \ to distinguish it from a backslash that precedes a substitution group, e.g. \1, hence r'\\\1'. To write that as a plain string, you'd need '\\\\\\1' — and nobody wants that.
Tim Ruddick
  • 1,375
  • 16
  • 24
10

Use repr()[1:-1]. In this case, the double quotes don't need to be escaped. The [-1:1] slice is to remove the single quote from the beginning and the end.

>>> x = raw_input()
I'm "stuck" :\
>>> print x
I'm "stuck" :\
>>> print repr(x)[1:-1]
I\'m "stuck" :\\

Or maybe you just want to escape a phrase to paste into your program? If so, do this:

>>> raw_input()
I'm "stuck" :\
'I\'m "stuck" :\\'
dp_
  • 135
  • 4
  • 3
    That doesn't work if the string is unicode, because you will have u and should run `repr(x)[2:-1]` – Antoine Pelisse Dec 11 '12 at 09:23
  • In python3.4, where all strings are unicode, this doesn't seem to work at all, unfortunately. Instead, `print(repr("I'm stuck")[1:-1])` prints `I'm stuck`. – dantiston Mar 04 '15 at 23:42
  • @dantiston this isn't because of the fact that the strings are all Unicode; it's because your example doesn't trigger `repr` to see a single quote as requiring escaping. – Karl Knechtel Aug 05 '22 at 01:30
  • 1
    @KarlKnechtel with seven years of hindsight, I agree; this answer only works in certain circumstances, not the general case of escaping special characters. – dantiston Aug 06 '22 at 21:52
3

As it was mentioned above, the answer depends on your case. If you want to escape a string for a regular expression then you should use re.escape(). But if you want to escape a specific set of characters then use this lambda function:

>>> escape = lambda s, escapechar, specialchars: "".join(escapechar + c if c in specialchars or c == escapechar else c for c in s)
>>> s = raw_input()
I'm "stuck" :\
>>> print s
I'm "stuck" :\
>>> print escape(s, "\\", ['"'])
I'm \"stuck\" :\\
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
spatar
  • 550
  • 1
  • 5
  • 15
2

If you only want to replace some characters you could use this:

import re

print re.sub(r'([\.\\\+\*\?\[\^\]\$\(\)\{\}\!\<\>\|\:\-])', r'\\\1', "example string.")
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
0

Note: This answer was written in response to the original question which was written in a way that it asked for a generic “function which can [be used] to escape special characters”, without specifying that these would be used for regular expressions, and without further specifying what special characters would have to be escaped.

In order to escape an arbitrary set of “special characters”, you can write a custom function that replaces each of these characters with an escaped variant. Something like this:

def escapeSpecialCharacters ( text, characters ):
    for character in characters:
        text = text.replace( character, '\\' + character )
    return text

>>> escapeSpecialCharacters( 'I\'m "stuck" :\\', '\'"' )
'I\\\'m \\"stuck\\" :\\'
>>> print( _ )
I\'m \"stuck\" :\
poke
  • 369,085
  • 72
  • 557
  • 602
0

use json:

import json
print(r"""(I'm "stuck" :\)""")               # (I'm "stuck" :\)
print(json.dumps(r"""(I'm "stuck" :\)"""))   # (I'm "stuck" :\)

for json to string with escape character

json.dumps(json.dumps(d))
andrewchan2022
  • 4,953
  • 45
  • 48