79

I have a string that contains both double-quotes and backslashes that I want to set to a variable in Python. However, whenever I try to set it, the quotes or slashes are either removed or escaped. Here's an example:

>>> foo = 'baz "\"'
>>> foo
'baz ""'

So instead of baz "\" like I want I'm getting baz "". If I then try to escape the backslash, it doesn't help either:

>>> foo = 'baz "\\"'
>>> foo
'baz "\\"'

Which now matches what I put in but wasn't what I originally wanted. How do you get around this problem?

codeforester
  • 39,467
  • 16
  • 112
  • 140
Chris Bunch
  • 87,773
  • 37
  • 126
  • 127
  • Despite the popularity, this is actually a rather poor form of the question - there are two entirely separate concerns: 1. Why does the single-backslash code not produce a backslash? 2. Why does the double-backslash code show two backslashes in the output (although the string actually contains only one backslash)? We have good canonicals for both of these now. Please use them to close future questions, not this one. – Karl Knechtel Aug 07 '22 at 04:05

5 Answers5

110

You're being mislead by output -- the second approach you're taking actually does what you want, you just aren't believing it. :)

>>> foo = 'baz "\\"'
>>> foo
'baz "\\"'
>>> print(foo)
baz "\"

Incidentally, there's another string form which might be a bit clearer:

>>> print(r'baz "\"')
baz "\"
Andrey Semakin
  • 2,032
  • 1
  • 23
  • 50
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • 1
    Is the fact that Python interactive interpreter outputs `'\\'` (including the escaping character) for `foo = '\\'` some sort of bug?, considering that I don't see this same type of output when you escape other characters, e.g. `foo = '\"'` produces `'"'` (without the escaping character). – Jaime Hablutzel Apr 12 '20 at 17:33
  • 2
    @JaimeHablutzel, no, it's not a bug. `'"'` is just as valid a way to describe a string with a single `"` character as `'\"'` is. By contrast, `'\'` is **not** a valid way to describe a single backslash character (since a lone slash looks like it's escaping the `'` that follows), so a lone backslash in a non-raw string **must** be escaped. – Charles Duffy Apr 12 '20 at 18:22
50

Use a raw string:

>>> foo = r'baz "\"'
>>> foo
'baz "\\"'

Note that although it looks wrong, it's actually right. There is only one backslash in the string foo.

This happens because when you just type foo at the prompt, python displays the result of __repr__() on the string. This leads to the following (notice only one backslash and no quotes around the printed string):

>>> foo = r'baz "\"'
>>> foo
'baz "\\"'
>>> print(foo)
baz "\"

And let's keep going because there's more backslash tricks. If you want to have a backslash at the end of the string and use the method above you'll come across a problem:

>>> foo = r'baz \'
  File "<stdin>", line 1
    foo = r'baz \'
                 ^  
SyntaxError: EOL while scanning single-quoted string

Raw strings don't work properly when you do that. You have to use a regular string and escape your backslashes:

>>> foo = 'baz \\'
>>> print(foo)
baz \

However, if you're working with Windows file names, you're in for some pain. What you want to do is use forward slashes and the os.path.normpath() function:

myfile = os.path.normpath('c:/folder/subfolder/file.txt')
open(myfile)

This will save a lot of escaping and hair-tearing. This page was handy when going through this a while ago.

Andrey Semakin
  • 2,032
  • 1
  • 23
  • 50
Harley Holcombe
  • 175,848
  • 15
  • 70
  • 63
  • 1
    If you print as Charles Duffy did above, it will appear correctly. When you're doing just "foo", Python is using the __repr__() function to display the string. It's output with an extra backslash so that when you assign the result to a variable the contents will be identical. – Kamil Kisiel Nov 19 '08 at 05:31
5

What Harley said, except the last point - it's not actually necessary to change the '/'s into '\'s before calling open. Windows is quite happy to accept paths with forward slashes.

infile = open('c:/folder/subfolder/file.txt')

The only time you're likely to need the string normpathed is if you're passing to to another program via the shell (using os.system or the subprocess module).

babbageclunk
  • 8,523
  • 1
  • 33
  • 37
1

If you are here for a filepath just use "\\"

import os
path = r"c:\file"+"\\"+"path"
os.path.normpath(path)

which will outputc:\file\path

Stephan Yazvinski
  • 484
  • 1
  • 6
  • 12
-1

Another way to end a string with a backslash is to end the string with a backslash followed by a space, and then call the .strip() function on the string.

I was trying to concatenate two string variables and have them separated by a backslash, so i used the following:

newString = string1 + "\ ".strip() + string2
Kevin Panko
  • 8,356
  • 19
  • 50
  • 61
James
  • 11
  • 1
    The only reason this works is because `"\ "` isn't a valid escape sequence, so the backslash remains in the string. Try `"\n".strip("n")` and see the difference. If the next version of Python defines backslash-space as a valid single character, this will stop working. – Mark Ransom Apr 25 '21 at 02:42
  • 2
    It’s better to do `r"\ ".strip()` or `r"\ "[:-1]`. – alexia Aug 18 '22 at 13:26