Parcours
/
Julia
Julia
/
Exercices
/
Chatbot à expressions régulières
Chatbot à expressions régulières

Chatbot à expressions régulières

Exercice d'apprentissage

Introduction

Les expressions régulières sont un moyen extrêmement souple de rechercher des motifs dans des strings, grâce à un langage dédié (DSL) conçu pour cet usage.

Comme plusieurs autres langages de programmation, Julia ne cherche pas à implémenter sa propre bibliothèque de regex. À la place, elle encapsule la populaire bibliothèque PCRE2, ce qui lui donne une syntaxe de regex identique à celle de (par exemple) Gleam, et très proche de celle de JavaScript.

Note

Ce programme Julia suppose que tu connais déjà la syntaxe de base des expressions régulières. On se concentrera uniquement sur les fonctionnalités propres à Julia.

Tu trouveras ci-dessous quelques ressources pour rafraîchir tes connaissances en expressions régulières.

L'interface de Julia avec les expressions régulières est décrite dans le manuel.

Une expression régulière en Julia est simplement une string précédée de r avant le guillemet ouvrant ". Toutes les fonctionnalités de base font partie de la bibliothèque standard.

En fait, beaucoup des fonctions déjà présentées dans le concept Strings sont conçues pour la recherche par expression régulière, comme 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

Des caractères de modification peuvent suivre le guillemet fermant, comme i pour une correspondance insensible à la casse.

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

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

Captures

Le plus souvent, on veut savoir ce qui correspond. Pour cela, on inclut des groupes de capture entre parenthèses dans l'expression régulière, puis on utilise la fonction 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

Bien sûr, une correspondance peut échouer. Le résultat sera alors la valeur spéciale Nothing à la place d'un RegexMatch, alors prépare-toi à le tester.

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

julia> typeof(m)
Nothing

julia> isnothing(m)
true

Bien que match commence par défaut au début de la string, on peut aussi préciser un décalage n pour ignorer les n premiers caractères.

# 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() ne trouve que la première correspondance dans la string cible : il n'existe pas de modificateur global comme dans certains autres langages.

On dispose à la place de eachmatch(), qui renvoie un itérateur de correspondances. L'évaluation est paresseuse, tu devras donc peut-être le convertir dans le format qui t'intéresse.

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"

Remplace

Une raison fréquente d'utiliser une expression régulière est de remplacer la correspondance par une autre string.

La fonction replace() a été présentée dans le concept Strings, avec des littéraux de chaîne comme motif de recherche. Cette même fonction peut exploiter toute la puissance des correspondances d'expressions régulières.

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

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

Le deuxième exemple ci-dessus montre comment des groupes de capture numérotés et nommés peuvent être utilisés dans le remplacement, au sein d'une string s" ".

Voir le manuel pour plus de détails : c'est un sujet qui ramène sans cesse la plupart des développeurs à la documentation !

Instructions

On t'a recruté comme spécialiste des expressions régulières dans une entreprise qui développe un chatbot.

L'entreprise en est à une phase très basique de développement, donc ta mission consiste à utiliser les expressions régulières pour améliorer la capacité du chatbot à comprendre et à générer du langage naturel.

Note

Dans un but d'apprentissage, merci de résoudre ces tâches à l'aide d'expressions régulières.

Nous savons que d'autres approches sont parfois possibles (et peuvent même être plus performantes !)

1. Vérifie la validité d'une commande

En plus d'être intelligent, le chatbot est aussi un assistant fidèle.

Pour poser une question au chatbot, l'utilisateur doit dire le mot « Chatbot » en première position de la commande.

Peu importe que le mot-clé soit en MAJUSCULES ou en minuscules. Ce qui compte ici, c'est la position du mot.

Implémente la fonction is_valid_command() qui aide le chatbot à reconnaître le moment où l'utilisateur lui donne une commande.

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. Supprime les emojis chiffrés

Le chatbot a du mal à comprendre comment les humains utilisent les emojis pour exprimer leurs émotions.

Quand le chatbot reçoit des messages d'utilisateurs, chaque emoji est représenté par « emoji » suivi de son numéro id.

Implémente la méthode remove_emoji() pour qu'elle prenne une string et supprime le chiffrement de tous les emojis du message.

Les lignes qui ne contiennent pas de texte d'emoji doivent être renvoyées sans modification.

Supprime simplement la chaîne de l'emoji. N'essaie pas de retoucher les espaces.

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. Vérifie la validité d'un numéro de téléphone

Dans le cadre du téléchargement des fonctionnalités du chatbot sur une application mobile, l'utilisateur est censé écrire un numéro de téléphone pendant la conversation.

Le problème, c'est que le chatbot ne peut lire et valider qu'un numéro ayant un format bien précis.

Si le numéro est valide (c'est-à-dire s'il correspond à la séquence de caractères décrite par l'expression régulière), le chatbot répond par un message qui remercie l'utilisateur et confirme le numéro. Si le numéro n'est pas valide, la fonction informe l'utilisateur que le numéro de téléphone est invalide.

Le format attendu est le suivant : (+##) ###-###-###

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. Récupère le lien d'un site web

Le chatbot est un logiciel vraiment curieux. Même s'il peut faire des recherches sur internet à propos d'un sujet précis, il aime demander aux utilisateurs des sites web sympas ou des URL pour aller chercher des informations pertinentes.

Exemple de conversation :

  • Chatbot : Salut username, j'aimerais apprendre à coder en JavaScript, tu connais un site sympa où je pourrais apprendre ?
  • Utilisateur : J'ai beaucoup appris sur exercism.org

Implémente la fonction getURL() qui renvoie un tableau contenant uniquement le lien de chaque site web.

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

5. Salue l'utilisateur

Pour stocker les données de toutes les personnes avec qui il a discuté, le chatbot sait récupérer le nom complet depuis le profil de l'utilisateur, sous cette forme : « smith, john ».

Ainsi, on veut que notre chatbot soit vraiment poli et fasse bonne impression.

Écris la fonction nice_to_meet_you() qui prend une string contenant le nom complet de l'utilisateur, et qui renvoie la string « Nice to meet you, John Smith »

julia> str = "Smith, John"

julia> nice_to_meet_you(str)
"Nice to meet you, John Smith"
Modifie via GitHub Le lien s'ouvre dans une nouvelle fenêtre ou un nouvel onglet
Julia Exercism

Prêt à commencer Chatbot à expressions régulières ?

Inscris-toi sur Exercism pour apprendre et maîtriser Julia avec 35 concepts128 exercices, et un vrai mentorat humain, le tout gratuitement.