As expressões regulares são uma forma bastante versátil de fazer correspondência de padrões em strings, usando uma linguagem de domínio específico (DSL) criada para essa finalidade.
Assim como várias outras linguagens de programação, Julia não tenta implementar a própria biblioteca de Regex. Em vez disso, ela encapsula a popular biblioteca PCRE2, oferecendo assim uma sintaxe de Regex idêntica à de (por exemplo) Gleam e muito parecida com a de Javascript.
Este programa de estudos de Julia pressupõe que você já conheça a sintaxe básica de Regex. Vamos nos concentrar apenas nos recursos específicos de Julia.
Abaixo estão alguns recursos para revisar seus conhecimentos de expressões regulares.
A interface de Julia com expressões regulares está descrita no manual.
Em Julia, uma expressão regular é simplesmente uma string precedida de r antes das aspas de abertura ".
Toda a funcionalidade básica faz parte da biblioteca padrão.
Na verdade, muitas das funções já discutidas no conceito Strings são feitas para buscas com Regex por padrão, 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
Caracteres modificadores podem vir depois das aspas de fechamento, como o i para uma correspondência que ignora maiúsculas e minúsculas.
julia> occursin(r"test", "Testing")
false
julia> occursin(r"test"i, "Testing")
true
Frequentemente, queremos saber o que corresponde ao padrão. Para isso, incluímos grupos de captura entre parênteses dentro da regex e depois usamos 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.
Nesse caso, o resultado será o valor especial Nothing em vez de um RegexMatch, então convém testar essa possibilidade.
# failed match
m = match(r"(not here)", "dissolve 25g sugar in 200ml water")
julia> typeof(m)
Nothing
julia> isnothing(m)
true
Embora match comece, por padrão, no início da string, também podemos especificar um deslocamento n para ignorar os primeiros 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")
Em Julia, match() encontra apenas a primeira correspondência na string alvo: não existe um modificador global como em algumas outras linguagens.
Em vez disso, temos eachmatch(), que retorna um iterador de correspondências.
Ele é avaliado de forma preguiçosa, então pode ser que você precise convertê-lo para o formato que quiser.
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"
Um motivo comum para usar uma Regex é substituir a correspondência por uma string diferente.
A função replace() foi discutida no conceito Strings, usando literais de string na busca.
A mesma função pode aproveitar 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 grupos de captura numerados e nomeados podem ser usados na substituição, dentro de uma string s" ".
Consulte o manual para mais detalhes: esse é um assunto que sempre obriga a maioria dos programadores a voltar à documentação!
Você foi contratado como Especialista em Expressões Regulares em uma empresa que está desenvolvendo um Chatbot.
Ele está numa fase bem inicial de desenvolvimento, então sua missão é usar Expressões Regulares para melhorar a capacidade do chatbot de entender e gerar linguagem natural.
Para fins de aprendizado, resolva essas tarefas usando Expressões Regulares.
Sabemos que às vezes existem alternativas (que podem até ser mais eficientes!)
Além de inteligente, o Chatbot também é um assistente leal.
Para pedir algo ao chatbot, o usuário precisa 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 que importa aqui é a posição da palavra.
Implemente a função is_valid_command() que ajuda o Chatbot a reconhecer quando o usuário está dando 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
O Chatbot tem dificuldade para entender como os humanos usam emojis para expressar suas emoções.
Quando o chatbot recebe mensagens do usuário, cada emoji é representado como “emoji” seguido do seu número id.
Implemente o método remove_emoji() para receber uma string e remover toda a criptografia dos emojis ao longo da mensagem.
As linhas que não contêm texto de emoji devem ser retornadas sem modificação.
Apenas remova a string do emoji. Não tente 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"
Como os recursos do chatbot são baixados em um aplicativo de celular, espera-se que o usuário 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 caracteres especificada pela expressão regular), o chatbot responde com uma mensagem agradecendo ao usuário e confirmando o número. Se o número for inválido, a função informa ao usuário 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. Mesmo podendo pesquisar na internet sobre um assunto específico, ele gosta de perguntar aos usuários sobre sites legais ou URLs para encontrar informações relevantes.
Exemplo de conversa:
Implemente a função getURL() que consegue retornar um array apenas com o link de cada site.
julia> getURL("I learned a lot from exercism.org")
["exercism.org"]
Para armazenar os dados de todas as pessoas que já conversaram com ele, o chatbot consegue obter o nome completo do perfil do usuário neste estilo: “smith, john”.
Assim, queremos que nosso chatbot seja bem educado e cause uma boa impressão.
Escreva a função nice_to_meet_you() que recebe uma string com o nome completo do usuário e retorna a string “Nice to meet you, John Smith”
julia> str = "Smith, John"
julia> nice_to_meet_you(str)
"Nice to meet you, John Smith"
Crie sua conta no Exercism para aprender e dominar Julia com 35 conceitos128 exercícios e mentoria humana de verdade, tudo de graça.