90 votes

Pourquoi 3 barres obliques égales à 4 dans une chaîne Python?

Pourriez-vous me dire pourquoi '?\\\?'=='?\\\\?' donne True ? Cela me rend fou et je ne trouve pas de réponse raisonnable ...

 >>> list('?\\\?')
['?', '\\', '\\', '?']
>>> list('?\\\\?')
['?', '\\', '\\', '?']
 

84voto

Daniel Martin Points 9148

Fondamentalement, parce que python est légèrement clémente barre oblique inverse de traitement. Citant https://docs.python.org/2.0/ref/strings.html :

Contrairement à la Norme C, tous les méconnu les séquences d'échappement sont laissées dans la chaîne inchangé, c'est à dire, la barre oblique inverse est à gauche de la chaîne.

(Italique dans l'original)

Par conséquent, en python, il n'est pas que de trois barres obliques inverses sont égaux à quatre, c'est que lorsque vous suivez barre oblique inverse avec un personnage tel que ?, les deux ensemble comme deux personnages, car \? ne correspond pas à une séquence d'échappement.

30voto

mhawke Points 10385

C'est parce que la barre oblique inverse agit comme un caractère d'échappement pour le personnage(s) qui suit immédiatement, si la combinaison représente une réelle séquence d'échappement. La douzaine de séquences d'échappement sont répertoriés ici. Ils comprennent les plus évidents tels que le saut de ligne \n, horizontal onglet \t, retour à la ligne \r et les plus obscures comme les nommés des caractères unicode à l'aide de \N{...}, par exemple, \N{WAVY DASH} ce qui représente des caractères unicode \u3030. Le point clé est que, si la séquence d'échappement n'est pas connue, la séquence de caractères est à gauche de la chaîne.

Une partie du problème est peut-être aussi que l'interpréteur Python sortie est de vous induire en erreur. C'est parce que les barres obliques inverses sont échappés lors de l'affichage. Toutefois, si vous imprimez ces chaînes, vous verrez le supplément de barres obliques inverses disparaître.

>>> '?\\\?'
'?\\\\?'
>>> 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

Pour vos exemples précis, dans le premier cas '?\\\?', la première \ échappe à la deuxième barre oblique inverse en laissant une seule barre oblique inverse, mais la troisième barre oblique inverse reste comme une barre oblique inverse, car \? n'est pas valide séquence d'échappement. Par conséquent, la chaîne résultante est - ?\\?.

Pour le deuxième cas '?\\\\?', la première barre oblique inverse échappe à la deuxième, et la troisième des antislashes le quatrième qui résultats dans la chaîne ?\\?.

C'est pourquoi trois barres obliques inverses est le même que quatre:

>>> '?\\\?' == '?\\\\?'
True

Si vous souhaitez créer une chaîne avec 3 barres obliques inverses vous pouvez échapper à chaque barre oblique inverse:

>>> '?\\\\\\?'
'?\\\\\\?'
>>> print('?\\\\\\?')
?\\\?

ou vous pourriez trouver "brut" des chaînes plus compréhensible:

>>> r'?\\\?'
'?\\\\\\?'
>>> print(r'?\\\?')
?\\\?

Ceci permet de s'échapper de la séquence de traitement pour la chaîne littérale. Voir les Littéraux de Chaîne pour plus de détails.

13voto

the paul Points 5176

Parce que \x dans une chaîne de caractères, lorsque x ne fait pas partie des caractères spéciaux comme le backslashable tel que n , r , t , 0 , etc., est évalué à une chaîne avec une barre oblique inversée, puis à x .

 >>> '\?'
'\\?'
 

7voto

rkh Points 1093

À partir du python analyse lexicale de la page sous les littéraux de chaîne: https://docs.python.org/2/reference/lexical_analysis.html

Il y a un tableau qui répertorie tous les reconnu les séquences d'échappement.

\\ est une séquence d'échappement qui est === \

\? n'est pas une séquence d'échappement et est === \?

donc, '\ \ \ \ ''\ \ 'suivi d'un' \ \ ''\ \ ' (deux échappés \)

et '\ \ \ ''\ \ ' suivi d'un '\' qui est aussi "\ \ " (un échappé \ et un cru \)

aussi, il convient de noter que python ne fait pas de distinction entre des apostrophes et des guillemets autour d'une chaîne de caractères littérale, à la différence de certains autres langues.

Donc, "String" et "String" sont exactement la même chose en python, elles n'affectent pas l'interprétation de séquences d'échappement.

1voto

Rainy Points 321

mhawke la réponse de couvre assez bien, je veux juste réitérer dans une forme plus concise et avec un minimum d'exemples qui illustrent ce comportement.

Je suppose qu'une chose à ajouter, c'est que la fuite de traitement se déplace de gauche à droite, de sorte qu' \n trouve d'abord la barre oblique inverse et puis regarde pour un personnage en fuite, se retrouve alors n et s'échappe; \\n trouve la première barre oblique inverse, trouve une seconde et s'échappe, se retrouve alors n et le considère comme un littéral n; \? trouve la barre oblique inverse et regarde pour un char de s'échapper, conclut ? qui ne peut pas être échappé, et ainsi de friandises \ comme un backslash.

Comme mhawke noté, la clé ici est que interactive interprète échappe à la barre oblique inverse lors de l'affichage d'une chaîne de caractères. Je devine la raison pour cela est de s'assurer que les chaînes de texte copié à partir de l'interprète dans l'éditeur de code sont valide python cordes. Toutefois, dans ce cas, cette allocation pour la commodité des causes de la confusion.

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X