tutorial pattern online number examples example python regex python-module rawstring

pattern - re.search python examples



¿Qué es exactamente una "expresión regex de cadena sin formato" y cómo se puede usar? (5)

El problema con el uso de una cadena normal para escribir expresiones regulares que contienen un / es que terminas escribiendo // para cada / . Así que los literales de cadena "stuff//things" y r"stuff/things" producen la misma cadena. Esto se vuelve especialmente útil si desea escribir una expresión regular que coincida con las barras diagonales inversas.

Usando cadenas normales, ¡una expresión regular que coincida con la cadena / sería "////" !

¿Por qué? Porque tenemos que escapar / dos veces: una para la sintaxis de la expresión regular y una para la sintaxis de la cadena.

Puede usar comillas triples para incluir líneas nuevas, como esta:

r''''''stuff/ things''''''

Tenga en cuenta que, por lo general, python consideraría / -newline como una continuación de línea, pero este no es el caso en cadenas sin formato. También tenga en cuenta que las barras invertidas aún escapan a las comillas en cadenas sin formato, pero se dejan en sí mismas. Entonces la cadena de texto sin procesar r"/"" produce la cadena /" . Esto significa que no puede finalizar un literal de cadena sin formato con una barra diagonal inversa.

Consulte la sección de análisis léxico de la documentación de Python para obtener más información.

De la documentación de python en regex , con respecto al carácter ''/' :

La solución es usar la notación de cadenas crudas de Python para patrones de expresión regulares; las barras invertidas no se manejan de ninguna manera especial en un literal de cadena con el prefijo ''r'' . Así que r"/n" es una cadena de dos caracteres que contiene ''/' y ''n'' , mientras que "/n" es una cadena de un carácter que contiene una nueva línea. Por lo general, los patrones se expresarán en el código de Python usando esta notación de cadena sin formato.

¿Qué es esta notación de cuerda en bruto? Si usa un formato de cadena sin formato, ¿significa eso "*" como un carácter literal en lugar de un indicador de cero o más? Obviamente, eso no puede ser correcto, de lo contrario, regex podría perder completamente su poder. Pero si es una cadena sin formato, ¿cómo reconoce los caracteres de nueva línea si "/n" es literalmente una barra invertida y una "n" ?

Yo no sigo

Editar por generosidad:

Estoy tratando de entender cómo una cadena regex sin formato coincide con líneas nuevas, pestañas y juegos de caracteres, por ejemplo, /w para palabras o /d para dígitos o todo lo demás, si los patrones de cuerda en bruto no reconocen barras diagonales inversas como algo más que caracteres comunes. Realmente podría usar algunos buenos ejemplos.


La mayoría de estas preguntas tienen muchas palabras en ellas y tal vez sea difícil encontrar la respuesta a su pregunta específica.

Si usa una cadena normal y pasa un patrón como "/ t" al analizador de RegEx, Python traducirá ese literal en un búfer con el byte de tabulación en él (0x09).

Si usa una cadena sin formato y pasa un patrón como r "/ t" al analizador de RegEx, Python no hace ninguna interpretación, y crea un búfer con dos bytes: ''/' y ''t''. (0x5c, 0x74).

El analizador de RegEx sabe qué hacer con la secuencia ''/ t'' - que coincide con una pestaña. También sabe qué hacer con el carácter 0x09, que también coincide con una pestaña. En su mayor parte, los resultados serán indistinguibles.

Entonces, la clave para entender lo que está sucediendo es reconocer que hay dos analizadores empleados aquí. El primero es el analizador de Python, y traduce su literal de cadena (o literal de cadena sin formato) en una secuencia de bytes. El segundo es el analizador de expresiones regulares de Python, y convierte una secuencia de bytes en una expresión regular compilada.


La respuesta de Zarkonnen responde su pregunta, pero no directamente. Déjame intentar ser más directo, y ver si puedo tomar la recompensa de Zarkonnen.

Quizás te resulte más fácil de entender si dejas de usar los términos "regex de cadena sin procesar" y "patrones de cadena sin procesar". Estos términos combinan dos conceptos separados: las representaciones de una cadena particular en el código fuente de Python, y qué expresión regular representa esa cadena.

De hecho, es útil pensar en estos dos lenguajes de programación diferentes, cada uno con su propia sintaxis. El lenguaje Python tiene un código fuente que, entre otras cosas, crea cadenas con ciertos contenidos y llama al sistema de expresiones regulares. El sistema de expresión regular tiene un código fuente que reside en objetos de cadena y coincide con cadenas. Ambos lenguajes utilizan la barra diagonal inversa como un carácter de escape.

Primero, comprenda que una cadena es una secuencia de caracteres (es decir, bytes o puntos de código Unicode, la distinción no importa mucho aquí). Hay muchas formas de representar una cadena en el código fuente de Python. Una cadena en bruto es simplemente una de estas representaciones. Si dos representaciones resultan en la misma secuencia de caracteres, producen un comportamiento equivalente.

Imagine una cadena de 2 caracteres, que consiste en el carácter de barra invertida seguido del carácter n . Si sabe que el valor del carácter para la barra diagonal inversa es 92, y para n es 110, entonces esta expresión genera nuestra cadena:

s = chr(92)+chr(110) print len(s), s 2 /n

La notación de cadena de Python convencional "/n" no genera esta cadena. En cambio, genera una cadena de un carácter con un carácter de nueva línea. Python documenta 2.4.1. Los literales de cadena dicen: "El carácter de barra diagonal inversa (/) se usa para escapar de caracteres que de otro modo tienen un significado especial, como nueva línea, barra diagonal inversa o el carácter de comillas".

s = "/n" print len(s), s 1  

(Tenga en cuenta que la nueva línea no es visible en este ejemplo, pero si mira cuidadosamente, verá una línea en blanco después del "1").

Para obtener nuestra cadena de dos caracteres, debemos usar otra barra invertida para escapar del significado especial de la barra invertida original:

s = "//n" print len(s), s 2 /n

¿Qué sucede si quiere representar cadenas que tienen muchos caracteres de barra invertida en ellas? Python documenta 2.4.1. Los literales de cadena continúan, "Los literales de cadena opcionalmente pueden estar prefijados con una letra ''r'' o ''R'', tales cadenas se llaman cadenas crudas y usan reglas diferentes para interpretar secuencias de escape de barra invertida." Aquí está nuestra cadena de dos caracteres, usando representación de cadena sin formato:

s = r"/n" print len(s), s 2 /n

Así que tenemos tres representaciones de cadenas diferentes, todas dando la misma cadena o secuencia de caracteres:

print chr(92)+chr(110) == "//n" == r"/n" True

Ahora, pasemos a expresiones regulares. Los documentos de Python, 7.2. re - Las operaciones de expresión regular dicen: "Las expresiones regulares usan el carácter de barra invertida (''/') para indicar formas especiales o para permitir el uso de caracteres especiales sin invocar su significado especial. Esto choca con el uso del mismo carácter por parte de Python para el mismo propósito en cadenas literales ... "

Si desea un objeto de expresión regular Python que coincida con un carácter de nueva línea, entonces necesita una cadena de 2 caracteres, que consiste en el carácter de barra invertida seguido del carácter n . Las siguientes líneas de código establecen un progreso para un objeto de expresión regular que reconoce un carácter de nueva línea:

prog = re.compile(chr(92)+chr(110)) prog = re.compile("//n") prog = re.compile(r"/n")

Entonces, ¿por qué es que "Por lo general, los patrones se expresarán en el código de Python con esta notación de cadena sin formato". ? Debido a que las expresiones regulares son frecuentemente cadenas estáticas, que están convenientemente representadas como cadenas literales. Y a partir de las diferentes anotaciones literales de cadenas disponibles, las cadenas sin formato son una opción conveniente, cuando la expresión regular incluye una barra invertida .

Preguntas

P : ¿qué pasa con la expresión re.compile(r"/s/tWord") ? R : Es más fácil de entender separando la cadena de la compilación de expresiones regulares y entendiéndolas por separado.

s = r"/s/tWord" prog = re.compile(s)

La cadena s contiene ocho caracteres: una barra diagonal inversa , una s , una barra diagonal inversa , una t , y luego cuatro caracteres Word .

P : ¿Qué sucede con los caracteres de tabulación y espacio? R : En el nivel de lenguaje de Python, la cadena s no tiene carácter de tabulación y espacio . Comienza con cuatro caracteres: barra diagonal inversa , barra invertida , t . El sistema de expresión regular, mientras tanto, trata esa cadena como código fuente en el lenguaje de expresiones regulares, donde significa "hacer coincidir una cadena que consiste en un carácter de espacio en blanco, un carácter de tabulación y los cuatro caracteres Word .

P : ¿Cómo los empareja si eso está siendo tratado como backlash-s y backslash-t? R : Tal vez la pregunta sea más clara si las palabras "usted" y "eso" se vuelven más específicas: ¿cómo se relaciona el sistema de expresión regular con las expresiones backlash-s y backslash-t? Como ''cualquier carácter de espacio en blanco'' y como ''carácter de tabulación ''.

P : ¿O qué pasa si tienes la cadena de 3 caracteres backslash-n-newline? R : En el lenguaje Python, la barra diagonal inversa de cadena de tres caracteres puede representarse como la cadena convencional "//n/n" , o cadena r"/n" "/n" más convencional r"/n" "/n" , o de otras maneras . El sistema de expresión regular coincide con la cadena de 3 caracteres barra invertida y nueva línea cuando encuentra dos caracteres consecutivos de línea nueva .

NB Todos los ejemplos y referencias de documentos son para Python 2.7.

Actualización : aclaraciones incorporadas de las respuestas de @Vladislav Zorov y @ m.buettner, y de la pregunta de seguimiento de @Aerovistae.


La sección correspondiente del manual de Python ("literales de cadena y bytes") tiene una explicación clara de los literales de cadena sin formato:

Los literales tanto de cadena como de bytes pueden tener como prefijo una letra ''r'' o ''R''; tales cadenas se llaman cadenas sin formato y tratan las barras diagonales inversas como caracteres literales. Como resultado, en literales de cadenas, los escapes ''/ U'' y ''/ u'' en cadenas sin formato no se tratan de manera especial. Dado que los literales unicode sin procesar de Python 2.x se comportan de manera diferente a los de Python 3.x, la sintaxis ''ur'' no es compatible.

Nuevo en la versión 3.3: el prefijo ''rb'' de los literales de bytes sin formato se ha agregado como sinónimo de ''br''.

Nuevo en la versión 3.3: se reintrodujo el soporte para el literal heredado Unicode (u''value '') para simplificar el mantenimiento de las bases de código dobles de Python 2.xy 3.x. Ver PEP 414 para más información.

En las cadenas de comillas triples, las nuevas líneas y las comillas no guardadas están permitidas (y se conservan), excepto que tres comillas no guardadas en una fila terminan la cadena. (Una "cita" es el carácter utilizado para abrir la cadena, es decir, ''o''.)

A menos que exista 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:

Secuencia de escape Significado Notas

/ newline Backslash y newline ignorados
/ Backslash ()
/' Una frase ('')
/ "Doble cita (")
/ a ASCII Bell (BEL)
/ b Retroceso ASCII (BS)
/ f ASCII Formfeed (FF)
/ n ASCII Linefeed (LF)
retorno de carro ASCII (CR)
/ t Pestaña horizontal ASCII (TAB) / v Pestaña vertical ASCII (VT)
Personaje con valor octal ooo (1,3)
/ xhh Personaje con valor hexadecimal hh (2,3)

Las secuencias de escape solo reconocidas en literales de cadena son:

Secuencia de escape Significado Notas / N {nombre} Nombre del carácter con nombre en la base de datos Unicode (4) / uxxxx Carácter con valor hexadecimal de 16 bits xxxx (5) / Uxxxxxxxx Carácter con valor hexadecimal de 32 bits xxxxxxxx (6)

Notas:

  1. Como en el Estándar C, se aceptan hasta tres dígitos octales.

  2. A diferencia del Estándar C, se requieren exactamente dos dígitos hexadecimales.

  3. En un literal de bytes, los escapes hexadecimal y octal denotan el byte con el valor dado. En un literal de cadena, estas escapes denotan un carácter Unicode con el valor dado.

  4. Modificado en la versión 3.3: se ha agregado soporte para alias de nombre [1].

  5. Las unidades de código individuales que forman partes de un par sustituto pueden codificarse usando esta secuencia de escape. Se requieren exactamente cuatro dígitos hexadecimales.

  6. Cualquier carácter Unicode se puede codificar de esta manera, pero los caracteres fuera del plano multilingüe básico (BMP) se codificarán utilizando un par suplente si se compila Python para usar unidades de código de 16 bits (el valor predeterminado). Se requieren exactamente ocho dígitos hexadecimales.

A diferencia del Estándar C, todas las secuencias de escape no reconocidas quedan en la cadena sin cambios, es decir, la barra invertida queda en la cadena. (Este comportamiento es útil cuando se depura: si una secuencia de escape está mal escrita, el resultado resultante se reconoce más fácilmente como roto). También es importante tener en cuenta que las secuencias de escape solo reconocidas en cadenas literales caen en la categoría de escapes no reconocidos por bytes literales.

Incluso en una cadena sin formato, 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 .


Pareces estar luchando con la idea de que un RegEx no es parte de Python, sino un lenguaje de programación diferente con su propio analizador y compilador. Las cadenas sin formato te ayudan a obtener el "código fuente" de un RegEx de forma segura en el analizador de RegEx, que luego asignará significado a secuencias de caracteres como /d , /w , /n , etc.

El problema existe porque Python y RegExps usan / como carácter de escape, que es, por cierto, una coincidencia: hay idiomas con otros caracteres de escape (como "` n "para una nueva línea, pero incluso allí tienes que usar" / n "en RegExps). La ventaja es que no necesita diferenciar entre cadenas sin procesar y sin formato en estos lenguajes, no intentarán convertir el texto ni eliminarlo, ya que reaccionan a diferentes secuencias de escape.