Почему исходные строковые литералы Python не заканчиваются одним обратным слэшем?

Технически, любое нечетное количество обратной косой черты, как описано в документации.

>>> 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

Похоже, что парсер мог просто рассматривать обратные слэши в необработанных строках как обычные символы (не в этом ли смысл необработанных строк?), но я, вероятно, упускаю что-то очевидное.

Ответ 1

Причина объясняется в той части этого раздела, которую я выделил жирным шрифтом:

Строковые кавычки могут быть экранированы с помощью обратная косая черта,, но обратная косая черта остается в строке; например, r"\"" является действительный строковый литерал, состоящий из двух символы: обратная косая черта и двойная цитаты; r"\" не является допустимой строкой буквально (даже исходная строка не может закончиться в нечетном числе обратных косых черт). В частности, необработанная строка не может завершиться в одной обратной косой чертой (поскольку обратная косая черта избежит следующих символ цитаты). Отметим также, что одиночная обратная косая черта, сопровождаемая символом новой строки интерпретируется как эти два символа как часть строки, а не как строка продолжение.

Таким образом, сырые строки не являются 100% сырыми, есть еще рудиментарная обратная косая обработка.

Ответ 2

Все неправильное представление о необработанных строках python состоит в том, что большинство людей думает, что обратная косая черта (в пределах необработанной строки) является обычным символом, как и все остальные. Это не. Ключом к пониманию является эта последовательность python tutorial:

Когда присутствует префикс ' r' или R ', символ, следующий за обратная косая черта включена в строку без изменений, и все обратная косая черта остается в строке

Таким образом, любой символ, следующий за обратным слэшем , является частью необработанной строки. Когда синтаксический анализатор вводит необработанную строку (не однокодовый) и встречает обратную косую черту, она знает, что есть 2 символа (обратная косая черта и char после нее).

Таким образом:

r'abc\d ' содержит a, b, c, \, d

r'abc\'d' содержит a, b, c, \, ', d

r'abc\'' содержит a, b, c, \, '

и

r'abc\' содержит a, b, c, \,', но теперь нет завершающей цитаты.

Последний случай показывает, что согласно документации теперь синтаксический анализатор не может найти закрывающую цитату, поскольку последний qoute, который вы видите выше, является частью строки ie. обратная косая черта не может быть последней здесь, поскольку она "поглотит" закрытие строки char.

Ответ 3

Так оно и есть! Я рассматриваю это как один из тех небольших дефектов в python!

Я не думаю, что для этого есть веская причина, но это определенно не анализирует; это действительно легко разобрать необработанные строки с\в качестве последнего символа.

Уловка, если вы разрешаете\быть последним символом в исходной строке, тогда вы не сможете поставить "внутри необработанной строки". Кажется, что python пошел, разрешив "вместо того, чтобы разрешить\как последний символ.

Однако это не должно вызывать никаких проблем.

Если вы беспокоитесь о том, что не можете легко писать патчи с папками Windows, например c:\mypath\, тогда не беспокойтесь, потому что вы можете представить их как r"C:\mypath", и если вам нужно добавить имя подкаталога, Не делайте этого с конкатенацией строк, потому что это не правильный способ сделать это в любом случае! используйте os.path.join

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

Ответ 4

Другим трюком является использование chr (92), поскольку оно оценивается как "\".

Недавно мне пришлось очистить цепочку обратных косых черт, а следующий трюк:

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

Я понимаю, что это не заботится о "почему", но поток привлекает многих людей, которые ищут решение непосредственной проблемы.

Ответ 5

Для того, чтобы вы закончили необработанную строку с косой чертой, я предлагаю вам использовать этот трюк:

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

Ответ 6

Так как\"разрешено внутри необработанной строки, то оно не может использоваться для идентификации конца строкового литерала.

Почему бы не перестать анализировать строковый литерал, когда вы сталкиваетесь с первым "?

Если это так, тогда\"не будет разрешено внутри строкового литерала. Но это так.

Ответ 7

Причиной того, почему r'\' является синтаксически неправильным, является то, что, хотя строковое выражение является исходным, используемые кавычки (одиночные или двойные) всегда должны быть убедительными, поскольку в противном случае они будут отмечать конец цитаты. Поэтому, если вы хотите выразить одну цитату внутри одной кавычки, нет другого способа, кроме использования \'. То же самое относится к двойным кавычкам.

Но вы можете использовать:

'\\'

Ответ 8

Другой пользователь, который с тех пор удалил свой ответ (не уверен, хотят ли они быть зачисленным), предположил, что разработчики языка Python могут упростить дизайн парсера, используя те же правила синтаксического анализа и расширяя экранированные символы до необработанной формы (если буква была отмечена как необработанная).

Я подумал, что это интересная идея, и я включаю ее как сообщество wiki для потомков.

Ответ 9

  Несмотря на свою роль, даже необработанная строка не может заканчиваться одним обратная косая черта, потому что обратная косая черта экранирует следующую цитату символ - вы все равно должны экранировать окружающий символ кавычки встроить его в строку. То есть r "... \" не является допустимой строкой литерал - необработанная строка не может заканчиваться нечетным числом обратных косых черт.
Если вам нужно завершить необработанную строку одной обратной косой чертой, вы можете использовать два и отрежь второй.

Ответ 10

Приступая к C, мне совершенно ясно, что один\работает как escape-символ, позволяющий помещать в строки специальные символы, такие как символы новой строки, вкладки и цитаты.

Это действительно запрещает\как последний символ, так как он сбежит из "и сделает дроссель синтаксического анализатора. Но как указано ранее\является законным.

Ответ 11

несколько советов:

1), если вам нужно манипулировать обратным слэшем для пути, тогда стандартный python-модуль os.path - ваш друг. например:

os.path.normpath( 'C:/папка1/')

2), если вы хотите создать строки с обратным слэшем в нем, но без обратного слэш в конце вашей строки, тогда необработанная строка будет вашим другом (используйте префикс 'r' перед вашей литеральной строкой). например:

r'\one \two \three'

3), если вам нужно префикс строки в переменной X с обратным слэшем, вы можете сделать это:

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), если вам нужно создать строку с обратной косой чертой в конце, тогда объедините подсказки 2 и 3:

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

теперь lilypond_statement содержит "\DisplayLilyMusic \upper"

длинный живой питон!:)

n3on

Ответ 12

Я столкнулся с этой проблемой и нашел частичное решение, которое хорошо для некоторых случаев. Несмотря на то, что python не может завершить строку одним обратным слешем, он может быть сериализован и сохранен в текстовом файле с одним обратным слешем в конце. Поэтому, если вам нужно сохранить текст с одной обратной косой чертой на вашем компьютере, это возможно:

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)

Кстати, он не работает с json, если вы создаете дамп с помощью библиотеки jthon python.

Наконец, я работаю со Spyder и заметил, что если я открою переменную в текстовом редакторе Spider, дважды щелкнув ее имя в проводнике переменных, он будет представлен с одной обратной косой чертой и может быть скопирован в буфер обмена таким образом (это не очень полезно для большинства потребностей, но может быть для некоторых..).