1

The below fails with syntax error:

chars = r'''|'*+[]".?!-/,{}()&%$_;:#@=`~<>^\'''
# SyntaxError: EOF while scanning triple-quoted string literal 

Switching the last two characters causes the code to work as expected:

chars = r'''|'*+[]".?!-/,{}()&%$_;:#@=`~<>\^'''
print("Output: " + ''.join(chars))     
# Output: |'*+[]".?!-/,{}()&%$_;:#@=`~<>\^

Is this a python implementation issue, or did I miss something?

user
  • 30
  • 3

1 Answers1

0

This question has already been documented on Python FAQ documentation. So you can read through the details.

Extract from the FAQ:

  • Why can’t raw strings (r-strings) end with a backslash? More
    precisely, they can’t end with an odd number of backslashes: the
    unpaired backslash at the end escapes the closing quote character,
    leaving an unterminated string.

  • Raw strings were designed to ease creating input for processors
    (chiefly regular expression engines) that want to do their own
    backslash escape processing. Such processors consider an unmatched
    trailing backslash to be an error anyway, so raw strings disallow
    that. In return, they allow you to pass on the string quote character by escaping it with a backslash. These rules work well when r-strings are used for their intended purpose.

Unfortunately there is no way around it. You need to end it with another character or include a space. If you include a space, the length will change.

The trick to get the backslash as the last string is to add a space after the backslash.

char = r'''|'*+[]".?!-/,{}()&%$_;:#@=`~<>^\ '''
print ('last char:',char[-1], 'second last char', char[-2],'third last char', char[-3])

Here's the output of the above code:

last char:   second last char \ third last char ^

So you have to just change it to another character. The reason is \ is an escape character and it is taking the ' as a char.

My initial reaction was to add another backslash. However, that just adds the backslash to the string. See code below.

char = r'''|'*+[]".?!-/,{}()&%$_;:#@=`~<>^\\'''
print ('last char:',char[-1], 'second last char', char[-2],'third last char', char[-3])

The output is:

last char: \ second last char \ third last char ^

The only workaround I found is to include the space but to slice the string to [:-1]. You can do the following:

char = r'''|'*+[]".?!-/,{}()&%$_;:#@=`~<>^\ '''[:-1]
print ('last char:',char[-1], 'second last char', char[-2],'third last char', char[-3])

The output of this will be:

last char: \ second last char ^ third last char >
Joe Ferndz
  • 8,417
  • 2
  • 13
  • 33
  • I would be interested to know why I was downvoted. Happy to learn and improve – Joe Ferndz Jan 23 '21 at 01:57
  • Primarily because there's nothing special about putting a space after the backslash as opposed to any other character (including another backslash). Particularly, putting a space there doesn't make the backslash the last character, contrary to the line "The trick to get the backslash as the last string is to add a space after the backslash" in the answer. – user2357112 Jan 23 '21 at 02:00
  • Well, I think I did enough research and looked up documentation to ensure python does not have a way to solve for it. All that information has been shared in the answer. I will leave this answer this as is. Thanks for the clarification. – Joe Ferndz Jan 23 '21 at 02:04
  • 1
    Yeah this answers the question by linking the doc that I missed. The workaround (which slices using operator chars[:-1] with a space at the end) is mentioned in the FAQ that was linked as well – user Jan 24 '21 at 09:35