<jupyter_start><jupyter_text>Expresiones Regulares Las expresiones regulares, también llamadas regex o regexp, consisten en patrones que describen conjuntos de cadenas de caracteres.El módulo re contiene funciones para buscar patrones dentro de una cadena (search), comprobar si una cadena se ajusta a un determinado criterio descrito mediante un patrón (match), dividir la cadena usando las ocurrencias del patrón como puntos de ruptura (split) o para sustituir todas las ocurrencias del patrón por otra cadena (sub). Veremos estas funciones y alguna más en la próxima sección, pero por ahora, aprendamos algo más sobre la sintaxis de las expresiones regulares.  Patrones La expresión regular más sencilla consiste en una cadena simple, que describe un conjunto compuesto tan solo por esa misma cadena. Por ejemplo, veamos cómo la cadena “python” coincide con la expresión regular “python” usando la función match:<jupyter_code>import re

if re.match("python", "python"):
  print ("cierto")<jupyter_output>cierto<jupyter_text>Si quisiéramos comprobar si la cadena es “python”, “jython”, “cython” o cualquier otra cosa que termine en “ython”, podríamos utilizar el carácter comodín, el punto ‘.’:<jupyter_code>print(re.match(".ython", "python"))
print(re.match(".ython", "jython"))
print(re.match(".ython", "cython"))<jupyter_output><re.Match object; span=(0, 6), match='python'>
<re.Match object; span=(0, 6), match='jython'>
<re.Match object; span=(0, 6), match='cython'><jupyter_text>Para comprobar si la cadena consiste en 3 caracteres seguidos de un punto, por ejemplo, podríamos utilizar lo siguiente:<jupyter_code>print(re.match("...\.", "abc."))<jupyter_output><re.Match object; span=(0, 4), match='abc.'><jupyter_text>Si necesitáramos una expresión que sólo resultara cierta para las cadenas“python”, “jython” y “cython” y ninguna otra, podríamos utilizar el carácter ‘|’ para expresar alternativa escribiendo los tres subpatronescompletos:<jupyter_code>print(re.match("python|jython|cython", "python"))<jupyter_output><re.Match object; span=(0, 6), match='python'><jupyter_text>o bien tan solo la parte que pueda cambiar, encerrada entre paréntesis, formando lo que se conoce como un grupo. Los grupos tienen una gran importancia a la hora de trabajar con expresiones regulares y este no es su único uso, como veremos en la siguiente sección.<jupyter_code>print(re.match("(p|j|c)ython", "python"))<jupyter_output><re.Match object; span=(0, 6), match='python'><jupyter_text>Otra opción consistiría en encerrar los caracteres ‘p’, ‘j’ y ‘c’ entre corchetes para formar una clase de caracteres, indicando que en esa posición puede colocarse cualquiera de los caracteres de la clase.<jupyter_code>print(re.match("[pjc]ython", "python"))<jupyter_output><re.Match object; span=(0, 6), match='python'><jupyter_text>¿Y si quisiéramos comprobar si la cadena es “python0”, “python1”, “python2”, ... , “python9”? En lugar de tener que encerrar los 10 dígitos dentro de los corchetes podemos utilizar el guión, que sirve para indicarrangos. Por ejemplo a-d indicaría todas las letras minúsculas de la ‘a’ a la ‘d’; 0-9 serían todos los números de 0 a 9 inclusive.<jupyter_code>print(re.match("python[0-9]", "python0"))<jupyter_output><re.Match object; span=(0, 7), match='python0'><jupyter_text>Si quisiéramos, por ejemplo, que el último carácter fuera o un dígito o una letra simplemente se escribirían dentro de los corchetes todos los criterios, uno detras de otro.<jupyter_code>print(re.match("python[0-9a-zA-Z]", "pythonp"))<jupyter_output><re.Match object; span=(0, 7), match='pythonp'><jupyter_text>Es necesario advertir que dentro de las clases de caracteres los caracteresespeciales no necesitan ser escapados. Para comprobar si la cadena es “python.” o “python,”, entonces, escribiríamos:<jupyter_code>print(re.match("python[.,]", "python."))<jupyter_output><re.Match object; span=(0, 7), match='python.'><jupyter_text>y no<jupyter_code>print(re.match("python[\.,]", "python."))<jupyter_output><re.Match object; span=(0, 7), match='python.'><jupyter_text>ya que en este último caso estaríamos comprobando si la cadena es “python.”, “python,” o “python\”.Los conjuntos de caracteres también se pueden negar utilizando el símbolo ‘^’. La expresión “python[^0-9a-z]”, por ejemplo, indicaría que nos interesan las cadenas que comiencen por “python” y tengan como último carácter algo que no sea ni una letra minúscula ni un número.<jupyter_code>print(re.match("python[^0-9a-z]", "python+"))<jupyter_output><re.Match object; span=(0, 7), match='python+'><jupyter_text>El uso de [0-9] para referirse a un dígito no es muy común, ya que, al ser la comprobación de que un carácter es un dígito algo muy utilizado, existe una secuencia especial equivalente: ‘\d’. Existen otras secuenciasdisponibles que listamos a continuación:    - "\d" : un dígito. Equivale a [0-9]- "\D" : cualquier carácter que no sea un dígito. Equivale a [^0-9]- "\w" : cualquier caracter alfanumérico. Equivale a [a-zA-Z0-9_]- "\W" : cualquier carácter no alfanumérico. Equivale a [^a-zA-Z0-9_]- "\s" : cualquier carácter en blanco. Equivale a [ \t\n\r\f\v]- "\S" : cualquier carácter que no sea un espacio en blanco. Equivale a [^ \t\n\r\f\v] Veamos ahora cómo representar repeticiones de caracteres, dado que no sería de mucha utilidad tener que, por ejemplo, escribir una expresión regular con 30 caracteres ‘\d’ para buscar números de 30 dígitos. Para este menester tenemos los caracteres especiales +, * y ?, además de las llaves {}.El carácter + indica que lo que tenemos a la izquierda, sea un carácter como ‘a’, una clase como ‘[abc]’ o un subpatrón como (abc), puede encontrarse una o mas veces. Por ejemplo la expresión regular “python+” describiría las cadenas “python”, “pythonn” y “pythonnn”, pero no “pytho”, ya que debe haber al menos una n.El carácter * es similar a +, pero en este caso lo que se sitúa a su izquierda puede encontrarse cero o mas veces.El carácter ? indica opcionalidad, es decir, lo que tenemos a la izquierda puede o no aparecer (puede aparecer 0 o 1 veces).Finalmente las llaves sirven para indicar el número de veces exacto que puede aparecer el carácter de la izquierda, o bien un rango de veces que puede aparecer. Por ejemplo {3} indicaría que tiene que aparecer exactamente3 veces, {3,8} indicaría que tiene que aparecer de 3 a 8 veces, {,8} de 0 a 8 veces y {3,} tres veces o mas (las que sean).Otro elemento interesante en las expresiones regulares, para terminar, es la especificación de las posiciones en que se tiene que encontrar la cadena, esa es la utilidad de ^ y $, que indican, respectivamente, que el elemento sobre el que actúan debe ir al principio de la cadena o al final de esta.La cadena “http://mundogeek.net”, por ejemplo, se ajustaría a la expresión regular “^http”, mientras que la cadena “El protocolo es http” no lo haría, ya que el http no se encuentra al principio de la cadena.  Usando el módulo re Ya hemos visto por encima cómo se utiliza la función match del módulore para comprobar si una cadena se ajusta a un determinado patrón. El primer parámetro de la función es la expresión regular, el segundo, la cadena a comprobar y existe un tercer parámetro opcional que contienedistintos flags que se pueden utilizar para modificar el comportamientode las expresiones regulares.Al llamar al método group sin parámetros se nos devuelve el grupo 0 de la cadena reconocida. El grupo 0 es la subcadena reconocida por la expresión regular al completo, aunque no existan paréntesis que delimiten el grupo.<jupyter_code>mo = re.match("http://.+\.net", "http://mundogeek.net")
print (mo.group())<jupyter_output>http://mundogeek.net<jupyter_text>Podríamos crear grupos utilizando los paréntesis, como aprendimos en la sección anterior, obteniendo así la parte de la cadena que nos interese.<jupyter_code>mo = re.match("http://(.+)\.net", "http://mundogeek.net")
print (mo.group(0))
print (mo.group(1))<jupyter_output>http://mundogeek.net
mundogeek
{'fraction_non_alphanumeric': 0.0993734335839599, 'fraction_numerical': 0.009398496240601503, 'mean_word_length': 5.525756336876533, 'pattern_counts': {'":': 0, '<': 52, '<?xml version=': 0, '>': 52, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '13', 'dir': 'jupyter-structured-clean-dedup', 'id': '299228', 'license': 'OLDAP-2.5', 'n_tokens_mistral': 2741, 'n_tokens_neox': 2746, 'n_words': 1033, 'path': 'Expresiones_Regulares.ipynb', 'repo_name': 'victorricardo/tutorial-python', 'size': '7980'}