raw literal escape characters python string literals

escape - ¿Por qué los literales de cadena sin formato de Python no pueden terminar con una sola barra invertida?



raw string python 3 (11)

Técnicamente, cualquier número impar de barras invertidas, como se describe en los documentos .

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

Parece que el analizador solo podría tratar las barras invertidas en cadenas sin formato como caracteres regulares (¿no es eso de lo que se tratan las cadenas sin formato?), Pero probablemente me esté perdiendo algo obvio. TIA!


A pesar de su rol, incluso una cadena en bruto no puede terminar en una sola barra diagonal inversa, porque la barra invertida escapa al siguiente carácter de comillas, aún debe escapar del carácter de comillas circundante para incrustarlo en la cadena. Es decir, r "... /" no es un literal de cadena válido: una cadena sin formato no puede finalizar en un número impar de barras invertidas. Si necesita finalizar una cadena sin formato con una sola barra diagonal inversa, puede usar dos y cortar el segundo.


¡Esa es la forma en que está! ¡Lo veo como uno de esos pequeños defectos en Python!

No creo que haya una buena razón para eso, pero definitivamente no es un análisis sintáctico; es muy fácil analizar cadenas sin formato con / como último carácter.

El truco es que si permites que / sea el último carácter en una cadena en bruto, entonces no podrás poner "dentro de una cadena en bruto. Parece que Python fue con permitir" en lugar de permitir / como el último carácter.

Sin embargo, esto no debería causar ningún problema.

Si le preocupa no poder escribir fácilmente pathes de carpetas de Windows como c:/mypath/ entonces no se preocupe, por ejemplo, puede representarlos como r"C:/mypath" y, si necesita agregar un subdirectorio nombre, no lo hagas con la concatenación de cadenas, ¡porque no es la forma correcta de hacerlo de todos modos! use os.path.join

>>> import os >>> os.path.join(r"C:/mypath", "subfolder") ''C://mypath//subfolder''


Como / "está permitido dentro de la cadena sin formato. Entonces no se puede usar para identificar el final del literal de la cadena.

¿Por qué no detener el análisis sintáctico de la cadena cuando se encuentra con el primero "?

Si ese fuera el caso, entonces / "no estaría permitido dentro del literal de la cadena. Pero lo es.


Desde C, tengo muy claro que un único / funciona como un carácter de escape que le permite poner caracteres especiales como líneas nuevas, pestañas y comillas en cadenas.

Eso de hecho no permite / como último carácter ya que escapará del "y hará que el analizador sintáctico se estrangule. Pero como se señaló anteriormente / es legal.


El motivo por el cual r''/' es sintácticamente incorrecto es que, aunque la expresión de cadena es cruda, las comillas usadas (simples o dobles) siempre deben ser de escape, ya que marcarían el final de la cita de lo contrario. Entonces, si quiere expresar una comilla simple dentro de una cadena entre comillas simples, no hay otra manera que usar /' . Lo mismo aplica para las comillas dobles.

Pero podrías usar:

''//'


La razón se explica en la parte de esa sección que destaqué en negrita:

Las comillas de cadena se pueden escapar con una barra diagonal inversa, pero la barra invertida permanece en la cadena; por ejemplo, r"/"" es un literal de cadena válido que consta de dos caracteres: una barra diagonal inversa y una comilla doble; r"/" no es un literal de cadena válido (incluso una cadena cruda no puede terminar en un número impar de barras diagonales inversas). Específicamente, una cadena sin formato no puede terminar en una sola barra invertida (ya que la barra invertida escaparía del siguiente carácter de comillas). Tenga en cuenta también que una sola barra invertida seguida de una línea nueva se interpreta como esos dos caracteres como parte de la cadena, no como una continuación de línea .

Por lo tanto, las cadenas sin formato no son 100% crudas, todavía hay un procesamiento de barra invertida rudimentario.


Otro truco es usar chr (92) ya que se evalúa como "/".

Recientemente tuve que limpiar una cadena de barras diagonales inversas y el siguiente hizo el truco:

CleanString = DirtyString.replace(chr(92),'''')

Me doy cuenta de que esto no soluciona el "por qué", pero el hilo atrae a muchas personas que buscan una solución a un problema inmediato.


Otro usuario que ha borrado su respuesta (no está seguro de si les gustaría recibir crédito) sugirió que los diseñadores de Python pueden simplificar el diseño del analizador utilizando las mismas reglas de análisis y expandiendo los caracteres escapados a la forma cruda como una idea de último momento (si el literal fue marcado como crudo).

Pensé que era una idea interesante y la incluyo como wiki de la comunidad para la posteridad.


Para que finalices una cadena sin formato con una barra inclinada, te sugiero que puedas usar este truco:

>>> print r"c:/test"''//' test/


Todo el concepto erróneo sobre las cadenas sin formato de Python es que la mayoría de la gente piensa que la barra diagonal inversa (dentro de una cadena sin formato) es solo un carácter regular como todos los demás. No lo es. La clave para entender es la secuencia de tutorial de esta pitón:

Cuando hay un prefijo '' r '' o '' R '' presente, un carácter que sigue a una barra invertida se incluye en la cadena sin cambios, y todas las barras invertidas quedan en la cadena

Entonces cualquier personaje que siga una barra invertida es parte de una cadena sin formato. Una vez que el analizador ingresa una cadena sin formato (no unicode) y se encuentra con una barra invertida, sabe que hay 2 caracteres (una barra invertida y una char siguiendo).

De esta manera:

r''abc / d '' comprende a, b, c, /, d

r''abc / ''d'' comprende a, b, c, /, '', d

r''abc / '''' comprende a, b, c, /, ''

y:

r''abc / '' comprende a, b, c, /,'' pero ahora no hay una frase de terminación.

El último caso muestra que, de acuerdo con la documentación, ahora un analizador no puede encontrar la cotización de cierre ya que la última pregunta que ve arriba es parte de la cadena, es decir. la barra invertida no puede ser la última aquí, ya que ''devorará'' la cadena de caracteres que se cierra.


algunos consejos :

1) si necesita manipular la barra invertida para la ruta, entonces el módulo estándar de python os.path es su amigo. por ejemplo :

os.path.normpath (''c: / folder1 /'')

2) si quieres construir cadenas con barra invertida, PERO sin barra invertida al final de la cadena, la cadena cruda es tu amiga (usa el prefijo ''r'' antes de la cadena literal). por ejemplo :

r''/one /two /three''

3) si necesita poner un prefijo en una cadena en una variable X con una barra diagonal inversa, puede hacer esto:

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 necesita crear una cadena con una barra invertida al final, combine las sugerencias 2 y 3:

voice_name=''upper'' lilypond_display=r''/DisplayLilyMusic / '' # don''t forget the space at the end lilypond_statement=lilypond_display[:-1]+voice_name

ahora lilypond_statement contiene "/DisplayLilyMusic /upper"

¡Larga vida a Python! :)

n3on