Подскажите почему '?\\\?'=='?\\\\?'
дает True
? Это сводит меня с ума, и я не могу найти разумного ответа ...
>>> list('?\\\?')
['?', '\\', '\\', '?']
>>> list('?\\\\?')
['?', '\\', '\\', '?']
python
python-2.7
kozooh
источник
источник
list()
даже:>>> '?\\\?'
'?\\\\?'
Ответы:
В основном потому, что python немного снисходителен к обработке обратной косой черты. Цитата из https://docs.python.org/2.0/ref/strings.html :
(Выделено в оригинале)
Следовательно, в 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
, я ошибся. Это должно быть так,'?\\\?'=='?\\\\?'
как указывает вопрос, я это исправил.Поскольку
\x
в строке символов, когдаx
не один из специальных backslashable персонажей , какn
,r
,t
,0
и т.д., вычисляется в строке с помощью обратной косой черты и затемx
.>>> '\?' '\\?'
источник
Со страницы лексического анализа 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 \\?
источник