Pourquoi les lettres Python ne peuvent-elles pas se terminer par un simple antislash?
techniquement, tout nombre impair de tirets arrière, tel que décrit dans the docs .
>>> 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
il semble que l'analyseur pourrait simplement traiter les barres obliques dans les chaînes brutes comme des caractères réguliers (n'est-ce pas ce que les chaînes brutes sont tout au sujet?), mais je suis probablement manquer quelque chose d'évident. TIA!
11 réponses
la raison est expliquée dans la partie de cette section que j'ai mise en évidence en gras:
les citations de chaîne peuvent être échappées avec un backslash, mais le backslash reste dans la chaîne; par exemple,
r"\""
est un chaîne valide littérale comprenant deux caractères: un antislash et un double citation;r"\"
n'est pas une chaîne valide littéral (même une chaîne brute ne peut pas finir dans un nombre impair de barres obliques inverses). Plus précisément, une chaîne brute ne peut pas finir dans une seule barre oblique inverse (depuis la backslash échapperait à ce qui suit citation de caractères). Notez également qu'un backslash simple suivi d'une nouvelle ligne est interprété comme ces deux personnages dans le cadre de la chaîne, non pas comme une ligne continuation.
donc les cordes brutes ne sont pas 100% brutes, il y a encore un traitement rudimentaire des antislashs.
l'idée fausse sur les cordes brutes de python est que la plupart des gens pensent que backslash (dans une corde brute) est juste un caractère régulier comme tous les autres. Il n'est PAS. La clé à comprendre est la séquence de tutoriel de ce python:
Lorsqu'un préfixe r 'ou R ' est présent, un caractère suivant un backslash est inclus dans la chaîne sans changement, et tous backslashs sont laissés dans la chaîne
donc tout caractère qui suit un antislash est fait partie de la chaîne brute. Une fois que parser entre une chaîne brute (non unicode one) et rencontre un backslash il sait qu'il y a 2 caractères (un backslash et un char le suivant).
par ici:
r'ABC\d' comprend a, b, c,\, d
r'ABC\'d' comprend a, b, c,\,', d
r'ABC\ " comprend a, b, c,\, "
et:
r'ABC\' comprend a, b, c,\, ' mais il n'y a pas de citation finale maintenant.
Dernier cas montre que, selon la documentation, maintenant un analyseur impossible de trouver la citation de fermeture car le dernier qoute que vous voyez ci-dessus fait partie de la chaîne ie. backslash ne peut pas être Dernier ici car il va 'dévorer' chaîne de fermeture char.
C'est comme ça! Je vois cela comme un de ces petits défauts en python!
Je ne pense pas qu'il y ait une bonne raison pour cela, mais ce n'est certainement pas parsing; il est vraiment facile de parser des cordes brutes avec \ comme dernier caractère.
le hic est que, si vous autorisez \ à être le dernier caractère d'une chaîne brute, alors vous ne pourrez pas mettre " à l'intérieur d'une chaîne brute. Il semble que python soit allé avec permettre " au lieu de permettre \ comme dernier caractère.
cependant, cela ne devrait pas causer de problèmes.
si vous êtes inquiet de ne pas pouvoir écrire facilement les chemins de Chemise de windows tels que c:\mypath\
alors ne vous inquiétez pas, car, vous pouvez les représenter comme r"C:\mypath"
, et, si vous avez besoin d'ajouter un nom de sous-répertoire, ne le faites pas avec la concaténation de chaîne, car ce n'est pas la bonne façon de le faire de toute façon! use os.path.join
>>> import os
>>> os.path.join(r"C:\mypath", "subfolder")
'C:\mypath\subfolder'
un autre truc est d'utiliser chr(92) comme il évalue à"\".
j'ai récemment dû nettoyer une chaîne de tirets arrière et le suivant a fait l'affaire:
CleanString = DirtyString.replace(chr(92),'')
je me rends compte que cela ne prend pas soin du" pourquoi " mais le fil attire de nombreuses personnes à la recherche d'une solution à un problème immédiat.
pour terminer une chaîne brute avec une barre oblique, je vous suggère d'utiliser cette astuce:
>>> print r"c:\test"'\'
test\
Depuis \" est autorisée à l'intérieur de la chaîne brute. Il ne peut pas être utilisé pour identifier la fin de la chaîne littérale.
Pourquoi ne pas arrêter l'analyse de la chaîne de caractères littérale lorsque vous rencontrez, le premier "?
si c'était le cas, alors \ " ne serait pas autorisé à l'intérieur de la chaîne littérale. Mais il est.
la raison pour laquelle r'\'
est syntaxiquement incorrect est que bien que l'expression string soit brute, les guillemets utilisés (simple ou double) doivent toujours être escape puisqu'ils marqueraient la fin de la citation autrement. Donc, si vous voulez exprimer une seule citation à l'intérieur d'une seule chaîne de citation, il n'y a pas d'autre moyen que d'utiliser \'
. De même pour les guillemets.
mais vous pouvez utiliser:
'\'
un autre utilisateur qui a depuis supprimé sa réponse (pas sûr s'il souhaite être crédité) a suggéré que les concepteurs du langage Python pourraient être en mesure de simplifier la conception de l'analyseur en utilisant les mêmes règles d'analyse et en étendant les caractères échappés à la forme brute comme une réflexion après coup (si le littéral était marqué comme brut).
j'ai pensé que c'était une idée intéressante et je l'inclus comme wiki communautaire pour la postérité.
en Venant de C c'est assez clair pour moi qu'un seul \ œuvres comme caractère d'échappement vous permettant de placer des caractères spéciaux tels que des sauts de ligne, les tabulations et les citations dans les chaînes.
qui ne permet en effet \ comme dernier caractère car il va échapper à la " et faire l'étouffement de l'analyseur. Mais comme indiqué plus haut \ est juridique.
malgré son rôle, même une corde brute ne peut pas se terminer en une seule backslash, parce que le backslash échappe à la citation suivante personnage, vous devez échapper l'entourant de guillemets à l'intégrer dans la chaîne. C'est, r"...\" n'est pas une chaîne valide literal-une chaîne brute ne peut pas se terminer par un nombre impair de backslashs.
Si vous avez besoin d'arrêter une chaîne brute avec un seul antislash, vous pouvez utiliser deux et découpez le deuxième.
quelques conseils:
1) si vous avez besoin de manipuler backslash pour path, alors standard Python module os.chemin d'accès est votre ami. par exemple:
os.chemin.normpath("c:/folder1/')
2) Si vous voulez construire des chaînes avec backslash mais sans backslash à la fin de votre chaîne, alors la chaîne brute est votre ami (utilisez le préfixe 'r' avant votre chaîne littérale). par exemple:
r'\one \two \three'
3) Si vous avez besoin de préfixer une chaîne dans une variable X avec un antislash alors vous pouvez faire ceci:
X='dummy'
bs=r'\ ' # don't forget the space after backslash or you will get EOL error
X2=bs[0]+X # X2 now contains \dummy
4) Si vous avez besoin de créer une chaîne avec un antislash à la fin, puis combiner la pointe 2 et 3:
voice_name='upper'
lilypond_display=r'\DisplayLilyMusic \ ' # don't forget the space at the end
lilypond_statement=lilypond_display[:-1]+voice_name
maintenant lilypond_statement contient "\DisplayLilyMusic \upper"
vive python ! :)
n3on