online - re.findall python example
Python regex-r prefix (3)
No todas las secuencias que involucran barras diagonales inversas son secuencias de escape. /t
y /f
son, por ejemplo, pero /s
no lo es. En un literal de cadena no cruda, cualquier /
que no sea parte de una secuencia de escape se ve como simplemente otro /
:
>>> "/s"
''//s''
>>> "/t"
''/t''
/b
es una secuencia de escape, sin embargo, por lo que el ejemplo 3 falla. (Y sí, algunas personas consideran este comportamiento bastante desafortunado).
¿Alguien puede explicar por qué funciona el siguiente ejemplo 1, cuando no se utiliza el prefijo r? Pensé que el prefijo r debe usarse siempre que se usen secuencias de escape. El ejemplo 2 y el ejemplo 3 demuestran esto ..
# example 1
import re
print (re.sub(''/s+'', '' '', ''hello there there''))
# prints ''hello there there'' - not expected as r prefix is not used
# example 2
import re
print (re.sub(r''(/b/w+)(/s+/1/b)+'', r''/1'', ''hello there there''))
# prints ''hello there'' - as expected as r prefix is used
# example 3
import re
print (re.sub(''(/b/w+)(/s+/1/b)+'', ''/1'', ''hello there there''))
# prints ''hello there there'' - as expected as r prefix is not used
Porque /
comienzan secuencias de escape solo cuando son secuencias de escape válidas.
>>> ''/n''
''/n''
>>> r''/n''
''//n''
>>> print ''/n''
>>> print r''/n''
/n
>>> ''/s''
''/s''
>>> r''/s''
''//s''
>>> print ''/s''
/s
>>> print r''/s''
/s
Unless un prefijo ''r'' o ''R'', las secuencias de escape en cadenas se interpretan de acuerdo con reglas similares a las utilizadas por el Estándar C. Las secuencias de escape reconocidas son:
Escape Sequence Meaning Notes /newline Ignored // Backslash (/) /' Single quote ('') /" Double quote (") /a ASCII Bell (BEL) /b ASCII Backspace (BS) /f ASCII Formfeed (FF) /n ASCII Linefeed (LF) /N{name} Character named name in the Unicode database (Unicode only) /r ASCII Carriage Return (CR) /t ASCII Horizontal Tab (TAB) /uxxxx Character with 16-bit hex value xxxx (Unicode only) /Uxxxxxxxx Character with 32-bit hex value xxxxxxxx (Unicode only) /v ASCII Vertical Tab (VT) /ooo Character with octal value ooo /xhh Character with hex value hh
Nunca confíe en cadenas sin procesar para literales de ruta, ya que las cadenas sin procesar tienen un funcionamiento interno bastante peculiar , conocido por haber mordido a la gente en el culo:
Cuando hay presente un prefijo "r" o "R", 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. Por ejemplo, la cadena literal
r"/n"
consta de dos caracteres: una barra diagonal inversa y una "n" minúscula. 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 .
Para ilustrar mejor este último punto:
>>> r''/'
SyntaxError: EOL while scanning string literal
>>> r''/'''
"//'"
>>> ''/'
SyntaxError: EOL while scanning string literal
>>> ''/'''
"''"
>>>
>>> r''//'
''////'
>>> ''//'
''//'
>>> print r''//'
//
>>> print r''/'
SyntaxError: EOL while scanning string literal
>>> print ''//'
/
la ''r'' significa que la siguiente es una "cadena en bruto", es decir. los caracteres de barra invertida son tratados literalmente en lugar de significar un trato especial para el siguiente personaje.
http://docs.python.org/reference/lexical_analysis.html#literals
entonces ''/n''
es una línea nueva
y r''/n''
son dos caracteres: una barra diagonal inversa y la letra ''n''
Otra forma de escribirlo sería ''//n''
porque la primera barra invertida escapa del segundo
una forma equivalente de escribir esto
print (re.sub(r''(/b/w+)(/s+/1/b)+'', r''/1'', ''hello there there''))
es
print (re.sub(''(//b//w+)(//s+//1//b)+'', ''//1'', ''hello there there''))
Debido a la forma en que Python trata a los caracteres que no son caracteres de escape válidos, no son necesarias todas las barras diagonales inversas, por ejemplo, ''/s''==''//s''
sin embargo, lo mismo no es cierto para ''/b''
y ''//b''
. Mi preferencia es ser explícito y doblar todas las barras diagonales inversas.