Trilhas
/
Julia
Julia
/
Programa
/
Expressões regulares
Ex

Expressões regulares em Julia

4 exercícios

Sobre Expressões regulares

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

Assim como várias outras linguagens de programação, Julia não tenta implementar sua 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 semelhante à de JavaScript.

Note

Este programa de estudos de Julia assume que você já conhece a sintaxe básica de Regex. Vamos nos concentrar apenas nos recursos específicos de Julia.

Alguns recursos para revisar seus conhecimentos de expressões regulares estão listados abaixo.

A interface de Julia com expressões regulares é descrita no manual.

Uma expressão regular em Julia é simplesmente uma string precedida por 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 projetadas 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 da aspa de fechamento, como 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

Capturas

Com frequência, queremos saber o que correspondeu. Isso é feito incluindo grupos de captura entre parênteses na expressão regular e depois usando 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, então esteja preparado para testar isso.

# 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() só encontra a primeira correspondência na string de destino: não há modificador global como em algumas outras linguagens.

Em vez disso, temos eachmatch(), que retorna um iterador de correspondências. Isso é avaliado de forma preguiçosa, então pode ser que você precise convertê-lo para o formato desejado.

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"

Correspondências sobrepostas não são permitidas por padrão. Adicione overlap = true como argumento nomeado para alterar esse comportamento.

julia> eachmatch(r"aba", "abababa") |> collect  # matches at positions 1, 5
2-element Vector{RegexMatch}:
 RegexMatch("aba")
 RegexMatch("aba")

julia> eachmatch(r"aba", "abababa"; overlap = true) |> collect  # also matches at position 3
3-element Vector{RegexMatch}:
 RegexMatch("aba")
 RegexMatch("aba")
 RegexMatch("aba")

Substituição

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 para buscar. 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: este é um tópico que constantemente faz a maioria dos programadores voltar à documentação!

Editar via GitHub O link abre em uma nova janela ou aba

Aprenda Expressões regulares

A prática está bloqueada

Desbloqueie mais 3 exercícios para praticar Expressões regulares