Why can't Python's raw string literals end with a single backslash?

Question:

Technically, any odd number of backslashes, as described in the documentation.

>>> r''
  File "<stdin>", line 1
    r''
       ^
SyntaxError: EOL while scanning string literal
>>> r'\'
'\\'
>>> r'\'
  File "<stdin>", line 1
    r'\'
         ^
SyntaxError: EOL while scanning string literal

It seems like the parser could just treat backslashes in raw strings as regular characters (isn’t that what raw strings are all about?), but I’m probably missing something obvious.

Asked By: cdleary

||

Answers:

The reason for why r'' is syntactical incorrect is that although the string expression is raw the used quotes (single or double) always have to be escape since they would mark the end of the quote otherwise. So if you want to express a single quote inside single quoted string, there is no other way than using '. Same applies for double quotes.

But you could use:

'\'
Answered By: Gumbo

The reason is explained in the part of that section which I highlighted in bold:

String quotes can be escaped with a
backslash,
but the backslash remains
in the string; for example, r""" is a
valid string literal consisting of two
characters: a backslash and a double
quote; r"" is not a valid string
literal (even a raw string cannot end
in an odd number of backslashes).
Specifically, a raw string cannot end
in a single backslash (since the
backslash would escape the following
quote character). Note also that a
single backslash followed by a newline
is interpreted as those two characters
as part of the string, not as a line
continuation.

So raw strings are not 100% raw, there is still some rudimentary backslash-processing.

Answered By: oefe

That’s the way it is! I see it as one of those small defects in python!

I don’t think there’s a good reason for it, but it’s definitely not parsing; it’s really easy to parse raw strings with as a last character.

The catch is, if you allow to be the last character in a raw string then you won’t be able to put ” inside a raw string. It seems python went with allowing ” instead of allowing as the last character.

However, this shouldn’t cause any trouble.

If you’re worried about not being able to easily write windows folder pathes such as c:mypath then worry not, for, you can represent them as r"C:mypath", and, if you need to append a subdirectory name, don’t do it with string concatenation, for it’s not the right way to do it anyway! use os.path.join

>>> import os
>>> os.path.join(r"C:mypath", "subfolder")
'C:\mypath\subfolder'
Answered By: hasen

Another user who has since deleted their answer (not sure if they’d like to be credited) suggested that the Python language designers may be able to simplify the parser design by using the same parsing rules and expanding escaped characters to raw form as an afterthought (if the literal was marked as raw).

I thought it was an interesting idea and am including it as community wiki for posterity.

Answered By: cdleary

Since ” is allowed inside the raw string. Then it can’t be used to identify the end of the string literal.

Why not stop parsing the string literal when you encounter the first “?

If that was the case, then ” wouldn’t be allowed inside the string literal. But it is.

Answered By: Brian R. Bondy

Comming from C it pretty clear to me that a single works as escape character allowing you to put special characters such as newlines, tabs and quotes into strings.

That does indeed disallow as last character since it will escape the ” and make the parser choke. But as pointed out earlier is legal.

Answered By: Robert Ahlskog

some tips :

1) if you need to manipulate backslash for path then standard python module os.path is your friend. for example :

os.path.normpath(‘c:/folder1/’)

2) if you want to build strings with backslash in it BUT without backslash at the END of your string then raw string is your friend (use ‘r’ prefix before your literal string). for example :

r'one two three'

3) if you need to prefix a string in a variable X with a backslash then you can do this :

X='dummy'
bs=r' ' # don't forget the space after backslash or you will get EOL error
X2=bs[0]+X  # X2 now contains dummy

4) if you need to create a string with a backslash at the end then combine tip 2 and 3 :

voice_name='upper'
lilypond_display=r'DisplayLilyMusic  ' # don't forget the space at the end
lilypond_statement=lilypond_display[:-1]+voice_name

now lilypond_statement contains "DisplayLilyMusic upper"

long live python ! 🙂

n3on

Answered By: n3on

In order for you to end a raw string with a slash I suggest you can use this trick:

>>> print r"c:test"'\'
test

It uses the implicit concatenation of string literals in Python and concatenates one string delimited with double quotes with another that is delimited by single quotes. Ugly, but works.

Answered By: Charles Beattie

Another trick is to use chr(92) as it evaluates to “”.

I recently had to clean a string of backslashes and the following did the trick:

CleanString = DirtyString.replace(chr(92),'')

I realize that this does not take care of the “why” but the thread attracts many people looking for a solution to an immediate problem.

Answered By: Geekworking

The whole misconception about python’s raw strings is that most of people think that backslash (within a raw string) is just a regular character as all others. It is NOT. The key to understand is this python’s tutorial sequence:

When an ‘r‘ or ‘R‘ prefix is present, a character following a
backslash is included in the string without change, and all
backslashes are left in the string

So any character following a backslash is part of raw string. Once parser enters a raw string (non Unicode one) and encounters a backslash it knows there are 2 characters (a backslash and a char following it).

This way:

r’abcd’ comprises a, b, c, , d

r’abc’d’ comprises a, b, c, , ‘, d

r’abc” comprises a, b, c, , ‘

and:

r’abc’ comprises a, b, c, , ‘ but there is no terminating quote now.

Last case shows that according to documentation now a parser cannot find closing quote as the last quote you see above is part of the string i.e. backslash cannot be last here as it will ‘devour’ string closing char.

Answered By: Artur

Despite its role, even a raw string cannot end in a single
backslash, because the backslash escapes the following quote
character—you still must escape the surrounding quote character to
embed it in the string. That is, r”…” is not a valid string
literal—a raw string cannot end in an odd number of backslashes.
If you need to end a raw string with a single backslash, you can use
two and slice off the second.

Answered By: pawandeep singh

I encountered this problem and found a partial solution which is good for some cases. Despite python not being able to end a string with a single backslash, it can be serialized and saved in a text file with a single backslash at the end. Therefore if what you need is saving a text with a single backslash on you computer, it is possible:

x = 'a string\' 
x
'a string\' 

# Now save it in a text file and it will appear with a single backslash:

with open("my_file.txt", 'w') as h:
    h.write(x)

BTW it is not working with json if you dump it using python’s json library.

Finally, I work with Spyder, and I noticed that if I open the variable in spider’s text editor by double clicking on its name in the variable explorer, it is presented with a single backslash and can be copied to the clipboard that way (it’s not very helpful for most needs but maybe for some..).

Answered By: BossaNova
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.