Подскажите почему '?\\\?'=='?\\\\?'дает True? Это сводит меня с ума, и я не могу найти разумного ответа ...
>>> list('?\\\?')
['?', '\\', '\\', '?']
>>> list('?\\\\?')
['?', '\\', '\\', '?']
Подскажите почему '?\\\?'=='?\\\\?'дает True? Это сводит меня с ума, и я не могу найти разумного ответа ...
>>> list('?\\\?')
['?', '\\', '\\', '?']
>>> list('?\\\\?')
['?', '\\', '\\', '?']
list()даже:>>> '?\\\?' '?\\\\?'
Ответы:
В основном потому, что python немного снисходителен к обработке обратной косой черты. Цитата из https://docs.python.org/2.0/ref/strings.html :
В отличие от Стандартного C, все нераспознанные escape-последовательности остаются в строке неизменными, т. Е. В строке остается обратная косая черта .
(Выделено в оригинале)
Следовательно, в Python три обратных косых черты не равны четырем, а то, что, когда вы следуете за обратной косой чертой с таким символом, как ?, два вместе проходят как два символа, потому что \?это не распознанная escape-последовательность.
'escape''d'). Там вам даже не нужно запоминать других персонажей!
Это связано с тем, что обратная косая черта действует как escape-символ для символа (ов), следующего за ним, если комбинация представляет собой допустимую escape-последовательность. Здесь перечислены около дюжины управляющих последовательностей . Они включают в себя очевидные, такие как новая строка \n, горизонтальная табуляция \t, возврат каретки \rи более непонятные, такие как использование именованных символов Unicode \N{...}, например, \N{WAVY DASH}которые представляют символ Unicode \u3030. Однако ключевым моментом является то, что если escape-последовательность неизвестна, последовательность символов остается в строке как есть.
Частично проблема может заключаться в том, что вывод интерпретатора Python вводит вас в заблуждение. Это связано с тем, что при отображении символы обратной косой черты экранируются. Однако, если вы напечатаете эти строки, вы увидите, что лишние обратные косые черты исчезнут.
>>> '?\\\?'
'?\\\\?'
>>> print('?\\\?')
?\\?
>>> '?\\\?' == '?\\?' # I don't know why you think this is True???
False
>>> '?\\\?' == r'?\\?' # but if you use a raw string for '?\\?'
True
>>> '?\\\\?' == '?\\\?' # this is the same string... see below
True
Для ваших конкретных примеров в первом случае '?\\\?'первый \экранирует вторую обратную косую черту, оставляя одну обратную косую черту, но третья обратная косая черта остается обратной косой чертой, поскольку \?не является допустимой escape-последовательностью. Следовательно, в результате получается строка ?\\?.
Во втором случае '?\\\\?'первая обратная косая черта экранирует второй, а третья обратная косая черта экранирует четвертую, что приводит к строке ?\\?.
Вот почему три обратной косой черты - это то же самое, что четыре:
>>> '?\\\?' == '?\\\\?'
True
Если вы хотите создать строку с тремя обратными косыми чертами, вы можете избежать каждой обратной косой черты:
>>> '?\\\\\\?'
'?\\\\\\?'
>>> print('?\\\\\\?')
?\\\?
или вы можете найти "сырые" строки более понятными:
>>> r'?\\\?'
'?\\\\\\?'
>>> print(r'?\\\?')
?\\\?
Это включает обработку управляющей последовательности для строкового литерала. Подробнее см. Строковые литералы .
'?\\\?'=='?\\?'дает False, я ошибся. Это должно быть так, '?\\\?'=='?\\\\?'как указывает вопрос, я это исправил.
Со страницы лексического анализа Python под строковыми литералами по адресу: https://docs.python.org/2/reference/lexical_analysis.html
Есть таблица, в которой перечислены все распознанные escape-последовательности.
\\ - это escape-последовательность === \
\? не является escape-последовательностью и является === \?
так что '\\\\' - это '\\', за которым следует '\\', который равен '\\' (два экранированных \)
а '\\\' - это '\\', за которым следует '\', который также является '\\' (один экранированный \ и один необработанный \)
также следует отметить, что в отличие от некоторых других языков python не различает одинарные и двойные кавычки, окружающие строковый литерал.
Итак, «String» и «String» - это одно и то же в Python, они не влияют на интерпретацию управляющих последовательностей.
Ответ mhawke в значительной степени охватывает это, я просто хочу повторить его в более сжатой форме и с минимальными примерами, иллюстрирующими это поведение.
Я полагаю, что нужно добавить, что обработка экранирования перемещается слева направо, так что \nсначала находит обратную косую черту, а затем ищет символ, который нужно экранировать, затем находит nи экранирует его; \\nнаходит первую обратную косую черту, находит вторую и экранирует ее, затем находит nи видит в ней буквальное n; \?находит обратную косую черту и ищет символ для экранирования, находит, ?что не может быть экранировано, и поэтому рассматривает \как буквальную обратную косую черту.
Как заметил Махоук, ключевым моментом здесь является то, что интерактивный интерпретатор избегает обратной косой черты при отображении строки. Я предполагаю, что причина этого в том, чтобы гарантировать, что текстовые строки, скопированные из интерпретатора в редактор кода, являются действительными строками Python. Однако в данном случае учет удобства вызывает недоумение.
>>> print('\?') # \? is not a valid escape code so backslash is left as-is
\?
>>> print('\\?') # \\ is a valid escape code, resulting in a single backslash
'\?'
>>> '\?' # same as first example except that interactive interpreter escapes the backslash
\\?
>>> '\\?' # same as second example, backslash is again escaped
\\?