Czy możesz mi powiedzieć, dlaczego '?\\\?'=='?\\\\?'
daje True
? To doprowadza mnie do szału i nie mogę znaleźć rozsądnej odpowiedzi ...
>>> list('?\\\?')
['?', '\\', '\\', '?']
>>> list('?\\\\?')
['?', '\\', '\\', '?']
python
python-2.7
kozooh
źródło
źródło
list()
nawet:>>> '?\\\?'
'?\\\\?'
Odpowiedzi:
Zasadniczo dlatego, że Python jest nieco łagodniejszy w przetwarzaniu odwrotnego ukośnika. Cytowanie z https://docs.python.org/2.0/ref/strings.html :
(Podkreślenie w oryginale)
Dlatego w Pythonie nie chodzi o to, że trzy odwrotne ukośniki są równe czterem, ale o to, że po odwróconym ukośniku z takim znakiem
?
, te dwa razem przechodzą jako dwa znaki, ponieważ\?
nie jest to rozpoznawana sekwencja ucieczki.źródło
'escape''d'
.). Nie musisz nawet pamiętać innych postaci!Dzieje się tak, ponieważ ukośnik odwrotny działa jako znak zmiany znaczenia dla znaku (ów) bezpośrednio po nim, jeśli kombinacja reprezentuje prawidłową sekwencję ucieczki. Kilkunastu sekwencje są tutaj wymienione . Obejmują one oczywiste, takie jak znak nowej linii
\n
, tabulator poziomy\t
, powrót karetki\r
i bardziej niejasne, takie jak nazwane znaki unicode\N{...}
, np.\N{WAVY DASH}
Które reprezentują znak unicode\u3030
. Kluczową kwestią jest jednak to, że jeśli sekwencja ucieczki nie jest znana, sekwencja znaków pozostaje w ciągu bez zmian.Częścią problemu może być również to, że dane wyjściowe interpretera Pythona wprowadzają Cię w błąd. Dzieje się tak, ponieważ odwrotne ukośniki są usuwane podczas wyświetlania. Jeśli jednak wydrukujesz te ciągi, zobaczysz, że dodatkowe ukośniki odwrotne znikną.
>>> '?\\\?' '?\\\\?' >>> 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
Dla twoich konkretnych przykładów, w pierwszym przypadku
'?\\\?'
, pierwszy\
znak ucieka przed drugim ukośnikiem odwrotnym, pozostawiając pojedynczy ukośnik odwrotny, ale trzeci ukośnik odwrotny pozostaje ukośnikiem odwrotnym, ponieważ\?
nie jest prawidłową sekwencją ucieczki. Stąd wynikowy ciąg to?\\?
.W drugim przypadku
'?\\\\?'
pierwszy lewy ukośnik wymyka się drugiemu, a trzeci odwrotny ukośnik wymyka się czwartemu, co daje w wyniku ciąg?\\?
.Dlatego trzy ukośniki odwrotne to to samo, co cztery:
>>> '?\\\?' == '?\\\\?' True
Jeśli chcesz utworzyć ciąg z 3 odwrotnymi ukośnikami, możesz pominąć każdy lewy ukośnik:
>>> '?\\\\\\?' '?\\\\\\?' >>> print('?\\\\\\?') ?\\\?
lub może się okazać, że „surowe” ciągi znaków są bardziej zrozumiałe:
>>> r'?\\\?' '?\\\\\\?' >>> print(r'?\\\?') ?\\\?
To włącza przetwarzanie sekwencji ucieczki dla literału ciągu. Aby uzyskać więcej informacji, zobacz Literały ciągów .
źródło
'?\\\?'=='?\\?'
dajeFalse
, pomyliłem się. Powinno być'?\\\?'=='?\\\\?'
tak, jak wskazuje pytanie, poprawiłem to.Ponieważ
\x
w ciągu znaków, gdyx
nie jest jednym ze specjalnych znaków backslashable jakn
,r
,t
,0
, itp Zwraca ciąg znaków z odwrotnym ukośnikiem a potemx
.>>> '\?' '\\?'
źródło
Ze strony analizy leksykalnej Pythona pod literałami ciągów pod adresem : https://docs.python.org/2/reference/lexical_analysis.html
Istnieje tabela zawierająca wszystkie rozpoznane sekwencje specjalne.
\\ to sekwencja ucieczki, która jest === \
\? nie jest sekwencją ucieczki i jest === \?
więc „\\\\” to „\\”, po którym następuje „\\”, czyli „\\” (dwa znaki ucieczki \)
a „\\\” to „\\”, po którym następuje „\”, czyli również „\\” (jeden znak ze znakiem ucieczki \ i jeden surowy \)
należy również zauważyć, że w przeciwieństwie do niektórych innych języków python nie rozróżnia pojedynczych i podwójnych cudzysłowów otaczających literał łańcuchowy.
Zatem „String” i „String” to dokładnie to samo w Pythonie, nie wpływają one na interpretację sekwencji ucieczki.
źródło
odpowiedź mhawke prawie to pokrywa, chcę tylko powtórzyć to w bardziej zwięzłej formie i z minimalnymi przykładami, które ilustrują to zachowanie.
Myślę, że jedną rzeczą do dodania jest to, że przetwarzanie ucieczki przesuwa się od lewej do prawej, tak że
\n
najpierw znajduje ukośnik odwrotny, a następnie szuka znaku do ucieczki, a następnie znajduje gon
i ucieka;\\n
znajduje pierwszy ukośnik odwrotny, znajduje drugi ukośnik i pomija go, a następnie znajdujen
i widzi literę n;\?
znajduje odwrotny ukośnik i szuka znaku do ucieczki, wyszukuje,?
których nie można uciec, i dlatego traktuje\
jako dosłowny odwrotny ukośnik.Jak zauważył mhawke, kluczem jest tutaj to, że interaktywny interpreter wymyka się ukośnikiem odwrotnym podczas wyświetlania ciągu. Zgaduję, że powodem tego jest upewnienie się, że ciągi tekstowe skopiowane z interpretera do edytora kodu są prawidłowymi ciągami w języku Python. Jednak w tym przypadku ta ulga dla wygody powoduje zamieszanie.
>>> 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 \\?
źródło