Rutas
/
Julia
Julia
/
Ejercicios
/
Chatbot de expresiones regulares
Chatbot de expresiones regulares

Chatbot de expresiones regulares

Ejercicio de aprendizaje

Introducción

Las expresiones regulares son una forma muy versátil de hacer pattern matching sobre strings, usando un lenguaje de dominio específico (DSL) diseñado para ello.

Como otros tantos lenguajes de programación, Julia no intenta implementar su propia biblioteca de Regex. En su lugar, envuelve la popular biblioteca PCRE2, lo que le proporciona una sintaxis de Regex idéntica a la de (por ejemplo) Gleam y muy similar a la de JavaScript.

Note

Este temario de Julia da por supuesto que ya conoces la sintaxis básica de las Regex. Nos centraremos únicamente en las características específicas de Julia.

A continuación se enumeran algunos recursos para refrescar tus conocimientos sobre expresiones regulares.

La interfaz de Julia con las expresiones regulares se describe en el manual.

Una expresión regular en Julia no es más que un string precedido por r antes de la comilla de apertura ". Toda la funcionalidad básica forma parte de la biblioteca estándar.

De hecho, muchas de las funciones que ya se han tratado en el concepto Strings están diseñadas para búsquedas con Regex de forma estándar, como occursin().

julia> re = r"test$"
r"test$"

julia> typeof(re)
Regex

# Does a string end with "test"?
julia> occursin(re, "this is a test")
true

julia> occursin(re, "these are tests")
false

Tras la comilla de cierre pueden aparecer caracteres modificadores, como i para una coincidencia que no distingue entre mayúsculas y minúsculas.

julia> occursin(r"test", "Testing")
false

julia> occursin(r"test"i, "Testing")
true

Capturas

A menudo queremos saber qué coincide. Para ello se incluyen grupos de captura entre paréntesis dentro de la Regex y luego se usa la función match().

julia> m = match(r"(\d+g) .* (\d+ml)", "dissolve 25g sugar in 200ml water")
RegexMatch("25g sugar in 200ml", 1="25g", 2="200ml")

julia> m.captures
2-element Vector{Union{Nothing, SubString{String}}}:
 "25g"
 "200ml"

# how many matches?
julia> length(m.captures)
2

# what matched?
julia> m[1], m[2]
("25g", "200ml")

# Starting positions of the matches (character index)
julia> m.offsets
2-element Vector{Int64}:
 10
 23

Por supuesto, las coincidencias pueden fallar. En ese caso, el resultado será el valor especial Nothing en lugar de un RegexMatch, así que prepárate para comprobarlo.

# failed match
m = match(r"(not here)", "dissolve 25g sugar in 200ml water")

julia> typeof(m)
Nothing

julia> isnothing(m)
true

Aunque match empieza por defecto al principio del string, también podemos especificar un desplazamiento n para ignorar los primeros n caracteres.

# capture first match
julia> m = match(r"(\wat)", "cat, sat, mat")
RegexMatch("cat", 1="cat")

# ignore first 5 characters, then match
julia> m = match(r"(\wat)", "cat, sat, mat", 5)
RegexMatch("sat", 1="sat")

En Julia, match() solo encuentra la primera coincidencia dentro del string de destino: no existe un modificador global como en otros lenguajes.

En su lugar, tenemos eachmatch(), que devuelve un iterador de coincidencias. Se evalúa de forma perezosa, así que puede que tengas que convertirlo al formato que quieras.

julia> matches = eachmatch(r"(\wat)", "cat, sat, mat")
Base.RegexMatchIterator{String}(r"(\wat)", "cat, sat, mat", false)

# convert to vector
julia> collect(matches)
3-element Vector{RegexMatch}:
 RegexMatch("cat", 1="cat")
 RegexMatch("sat", 1="sat")
 RegexMatch("mat", 1="mat")

# convert with comprehension
julia> [m.match for m in matches]
3-element Vector{SubString{String}}:
 "cat"
 "sat"
 "mat"

# broadcast an anonymous function
julia> (m -> m.match).(matches)
3-element Vector{SubString{String}}:
 "cat"
 "sat"
 "mat"

Reemplazar

Un motivo habitual para usar una Regex es reemplazar la coincidencia por un string distinto.

La función replace() se trató en el concepto Strings, usando literales de string para buscar. Esa misma función puede aprovechar toda la potencia de las coincidencias de Regex.

julia> replace("some string", r"[aeiou]" => "*")
"s*m* str*ng"

julia> replace("first second", r"(\w+) (?<agroup>\w+)" => s"\g<agroup> \1")
"second first"

El segundo ejemplo de arriba muestra cómo se pueden usar tanto grupos de captura numerados como con nombre en el reemplazo, dentro de un string s" ".

Consulta el manual para más detalles: ¡este es un tema que obliga constantemente a la mayoría de los programadores a volver a la documentación!

Instrucciones

Te han contratado como especialista en expresiones regulares en una empresa que está desarrollando un chatbot.

Está en una fase de desarrollo muy básica, así que tu misión es usar expresiones regulares para mejorar la capacidad del chatbot de entender y generar lenguaje natural.

Note

Con fines de aprendizaje, resuelve estas tareas usando expresiones regulares.

Sabemos que a veces existen alternativas (¡y puede que incluso sean más eficientes!)

1. Comprobar si un comando es válido

Además de ser inteligente, el chatbot también es un asistente leal.

Para preguntarle algo al chatbot, el usuario debe decir la palabra «Chatbot» en la primera posición del comando.

No importa si la palabra clave está en mayúsculas o en minúsculas. Lo importante aquí es la posición de la palabra.

Implementa la función is_valid_command() que ayuda al chatbot a reconocer cuándo el usuario está dando un comando.

julia> is_valid_command("Chatbot, play a song from the 80's.")
True

julia> is_valid_command("Hey Chatbot, where is the closest pharmacy?")
False

julia> is_valid_command("CHATBOT, do you have a solution for this challenge?")
True

2. Eliminar los emojis cifrados

Al chatbot le cuesta entender cómo usan las personas los emojis para expresar sus emociones.

Cuando el chatbot recibe mensajes de los usuarios, cada emoji se representa como «emoji» seguido de su número id.

Implementa el método remove_emoji() para que tome un string y elimine todo el cifrado de emojis del mensaje.

Las líneas que no contengan el texto de un emoji deben devolverse sin modificar.

Elimina solo el texto del emoji. No intentes ajustar los espacios en blanco.

julia> remove_emoji("I love playing videogames emoji3465 it's one of my hobbies")
"I love playing videogames  it's one of my hobbies"

3. Comprobar si un número de teléfono es válido

Teniendo en cuenta la descarga de funcionalidades del chatbot en una aplicación móvil, se espera que el usuario escriba un número de teléfono durante la conversación.

El problema es que el chatbot solo puede leer y validar un número con un formato específico.

Si el número es válido (coincide con la secuencia de caracteres especificada por la expresión regular), el chatbot responde con un mensaje que agradece al usuario y confirma el número. Si el número no es válido, la función informa al usuario de que el número de teléfono no es válido.

El formato esperado es: (+##) ###-###-###

julia> check_phone_number("(+34) 659-771-594")
"Thanks! You can now download me to your phone."

julia> check_phone_number("659-771-594")
"Oops, it seems like I can't reach out to 659-771-594"

4. Obtener el enlace de un sitio web

El chatbot es un programa muy curioso. Aunque puede buscar en internet información sobre un tema concreto, le gusta preguntar a los usuarios por sitios web o URL interesantes donde encontrar información relevante.

Ejemplo de conversación:

  • Chatbot: Hola, usuario, me gustaría aprender a programar en JavaScript, ¿conoces algún sitio web interesante donde pueda aprender?
  • Usuario: Aprendí mucho en exercism.org

Implementa la función getURL() que es capaz de devolver un array solo con el enlace de cada sitio web.

julia> getURL("I learned a lot from exercism.org")
["exercism.org"]

5. Saludar al usuario

Para almacenar los datos de todas las personas con las que ha conversado, el chatbot puede obtener el nombre completo del perfil del usuario con este estilo: «smith, john».

De esta forma, queremos que nuestro chatbot sea muy educado y cause una buena impresión.

Escribe la función nice_to_meet_you() que toma un string con el nombre completo del usuario y devuelve el string «Nice to meet you, John Smith»

julia> str = "Smith, John"

julia> nice_to_meet_you(str)
"Nice to meet you, John Smith"
Editar en GitHub El enlace se abre en una ventana o pestaña nueva
Julia Exercism

¿Listo para empezar Chatbot de expresiones regulares?

Regístrate en Exercism para aprender y dominar Julia con 35 conceptos128 ejercicios y mentoría humana real, todo gratis.