Percursos
/
Julia
Julia
/
Exercícios
/
Chatbot de expressões regulares
Chatbot de expressões regulares

Chatbot de expressões regulares

Exercício de aprendizagem

Introdução

As expressões regulares são uma forma muito versátil de fazer correspondência de padrões em strings, recorrendo a uma linguagem específica de domínio (DSL) criada para esse efeito.

Tal como várias outras linguagens de programação, a Julia não tenta implementar a sua própria biblioteca de Regex. Em vez disso, usa a popular biblioteca PCRE2, proporcionando assim uma sintaxe de Regex idêntica à do (por exemplo) Gleam e muito semelhante à do Javascript.

Note

Este programa de estudos da Julia parte do princípio de que já conheces a sintaxe básica de Regex. Vamos concentrar-nos apenas nas funcionalidades específicas da Julia.

Abaixo encontras alguns recursos para refrescares os teus conhecimentos de expressões regulares.

A interface da Julia para expressões regulares está descrita no manual.

Uma expressão regular em Julia é simplesmente uma string precedida de r antes da " de abertura. Toda a funcionalidade básica faz parte da biblioteca padrão.

Na verdade, muitas das funções já abordadas no Conceito Strings estão concebidas, por omissão, para pesquisas com Regex, como é o caso de 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

Podem seguir-se carateres modificadores à aspa de fecho, como o i para uma correspondência que não distingue maiúsculas de minúsculas.

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

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

Capturas

Muitas vezes queremos saber o que corresponde ao padrão. Conseguimos isto incluindo grupos de captura entre parênteses dentro da regex e usando depois a função 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

Claro que as correspondências podem falhar. O resultado será então o valor especial Nothing em vez de um RegexMatch, por isso prepara-te para testar isso.

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

julia> typeof(m)
Nothing

julia> isnothing(m)
true

Apesar de match começar, por omissão, no início da string, também podemos especificar um deslocamento n para ignorar os primeiros n carateres.

# 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")

Em Julia, match() só encontra a primeira correspondência dentro da string de destino: não existe um modificador global como nalgumas outras linguagens.

Em vez disso, temos eachmatch(), que devolve um iterador de correspondências. A avaliação é preguiçosa, por isso podes ter de o converter para o formato que quiseres.

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"

Substituição

Uma razão comum para usar uma Regex é substituir a correspondência por uma string diferente.

A função replace() foi abordada no Conceito Strings, usando literais de string para procurar. A mesma função pode tirar partido de todo o poder da correspondência com 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"

O segundo exemplo acima mostra como tanto grupos de captura numerados como nomeados podem ser usados na substituição, dentro de uma string s" ".

Consulta o manual para mais detalhes: este é um tema que obriga constantemente a maioria dos programadores a voltar à documentação!

Instruções

Foste contratado como Especialista em Expressões Regulares numa empresa que está a desenvolver um chatbot.

Está numa fase muito básica de desenvolvimento, por isso a tua missão é usar expressões regulares para melhorar a capacidade do chatbot de compreender e gerar linguagem natural.

Note

Para fins de aprendizagem, resolve estas tarefas usando expressões regulares.

Sabemos que, por vezes, existem alternativas possíveis (e que podem até ser mais eficientes!)

1. Verifica se o comando é válido

Além de ser inteligente, o chatbot também é um assistente leal.

Para pedir algo ao chatbot, o utilizador tem de dizer a palavra “Chatbot” na primeira posição do comando.

Não importa se a palavra-chave está em maiúsculas ou minúsculas. O importante aqui é a posição da palavra.

Implementa a função is_valid_command() que ajuda o chatbot a reconhecer quando o utilizador está a dar um 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. Remove emojis encriptados

O chatbot tem dificuldade em compreender como as pessoas usam emojis para expressar as suas emoções.

Quando o chatbot recebe mensagens dos utilizadores, cada emoji é representado como “emoji” seguido do seu número id.

Implementa o método remove_emoji() para receber uma string e remover toda a encriptação dos emojis ao longo da mensagem.

As linhas que não contêm texto de emoji devem ser devolvidas sem alterações.

Remove apenas a string do emoji. Não tentes ajustar os espaços em branco.

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. Verifica se o número de telefone é válido

Tendo em conta a transferência de funcionalidades do chatbot para uma aplicação móvel, espera-se que o utilizador escreva um número de telefone durante a conversa.

O problema é que o chatbot só consegue ler e validar um número com um formato específico.

Se o número for válido (corresponder à sequência de carateres especificada pela expressão regular), o chatbot responde com uma mensagem a agradecer ao utilizador e a confirmar o número. Se o número for inválido, a função informa o utilizador de que o número de telefone não é válido.

O formato esperado é: (+##) ###-###-###

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"

O chatbot é um software muito curioso. Apesar de conseguir pesquisar na internet sobre um determinado tema, gosta de perguntar aos utilizadores por websites interessantes ou URLs onde possa encontrar informações relevantes.

Exemplo de conversa:

  • Chatbot: Olá, nome de utilizador, gostaria de aprender a programar em JavaScript. Conheces algum site interessante onde possa aprender?
  • Utilizador: Aprendi muito no exercism.org

Implementa a função getURL() que consegue devolver um array apenas com o link de cada website.

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

5. Cumprimenta o utilizador

Para armazenar dados de todas as pessoas que conversaram com ele, o chatbot consegue obter o nome completo a partir do perfil do utilizador neste formato: “smith, john”.

Assim, queremos que o nosso chatbot seja muito educado e cause uma boa impressão.

Escreve a função nice_to_meet_you() que recebe uma string com o nome completo do utilizador e devolve a string “Nice to meet you, John Smith”

julia> str = "Smith, John"

julia> nice_to_meet_you(str)
"Nice to meet you, John Smith"
Editar via GitHub A ligação abre numa nova janela ou separador
Julia Exercism

Estás pronto para começar Chatbot de expressões regulares?

Inscreve-te no Exercism para aprenderes e dominares Julia com 35 conceitos128 exercícios, e mentoria humana real, tudo grátis.