Почему необработанные строковые литералы Python не могут заканчиваться одним обратным слешем? - PullRequest
144 голосов
/ 15 марта 2009

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

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

Кажется, что синтаксический анализатор может просто рассматривать обратные слэши в необработанных строках как обычные символы (разве не в этом смысл необработанных строк?), Но я, вероятно, упускаю что-то очевидное. ТИА!

Ответы [ 12 ]

109 голосов
/ 15 марта 2009

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

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

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

77 голосов
/ 29 октября 2013

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

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

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

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

r'abc \ d ' включает a, b, c, \, d

r'abc \ 'd' включает a, b, c, \, ', d

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

и

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

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

19 голосов
/ 15 марта 2009

Так оно и есть! Я вижу это как один из тех небольших дефектов в Python!

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

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

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

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

>>> import os
>>> os.path.join(r"C:\mypath", "subfolder")
'C:\\mypath\\subfolder'
14 голосов
/ 02 ноября 2011

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

Мне недавно пришлось очистить строку от обратной косой черты, и вот что получилось:

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

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

10 голосов
/ 29 апреля 2011

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

>>> print r"c:\test"'\\'
test\
8 голосов
/ 15 марта 2009

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

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

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

3 голосов
/ 15 марта 2009

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

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

'\\'
2 голосов
/ 15 марта 2009

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

Мне показалось, что это интересная идея, и я включаю ее в вики сообщества для потомков.

1 голос
/ 30 декабря 2017

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

1 голос
/ 15 марта 2009

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

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

...