Julia Expressions régulières

Une expression régulière décrit un motif de correspondance de chaînes. Elle peut être utilisée pour vérifier si une chaîne contient une certaine sous-chaîne, remplacer les sous-chaînes correspondantes, ou extraire d'une chaîne les sous-chaînes qui satisfont à une certaine condition.

Julia possède des expressions régulières (regex) compatibles avec Perl.

Les trois formes d'expressions régulières en Julia sont la correspondance, la substitution et la transformation :

  • Correspondance : m// (peut aussi être abrégé en //, en omettant m)

  • Substitution : s///

  • Transformation : tr///

Ces trois formes sont généralement utilisées avec=~ou!~ensemble ; =~ indique une correspondance, et !~ indique aucune correspondance.

En Julia, la saisie d'expressions régulières utilise des préfixes qui commencent tousrpar :

Exemple

julia> re = r"^\s*(?:#|$)"
r"^\s*(?:#|$)"


julia> typeof(re)
Regex

Pour vérifier si une expression régulière correspond à une chaîne, utilisezoccursin:

Exemple

julia> occursin(r"^\s*(?:#|$)", "not a comment")
false

julia> occursin(r"^\s*(?:#|$)", "# a comment")
vrai

Comme vous pouvez le voir,occursinil ne renvoie que true ou false, ce qui indique si l'expression régulière donnée apparaît dans la chaîne. Cependant, généralement, nous ne voulons pas seulement savoir si la chaîne correspond, mais aussi comment elle correspond. Pour capturer les informations de correspondance, vous pouvez utiliser lamatchfonction :

Exemple

julia> match(r"^\s*(?:#|$)", "not a comment")

julia> match(r"^\s*(?:#|$)", "# a comment")
RegexMatch("#")

Si l'expression régulière ne correspond pas à la chaîne donnée, match renvoie nothing — une valeur spéciale qui n'affiche rien dans l'invite interactive. À part le fait de ne rien afficher, c'est une valeur parfaitement normale, qui peut être testée par programme :

Exemple

m = match(r"^\s*(?:#|$)", line)
if m === nothing
    println("not a comment")
else
    println("blank or comment")
end

Si l'expression régulière correspond, match renvoie un objet RegexMatch. Ces objets enregistrent la façon dont l'expression a correspondu, y compris la sous-chaîne correspondant au motif et toutes les sous-chaînes qui ont pu être capturées. L'exemple ci-dessus n'a capturé qu'une partie de la sous-chaîne correspondante, mais peut-être voulons-nous capturer tout texte non vide après le caractère de commentaire. Nous pouvons faire ceci :

Exemple

julia> m = match(r"^\s*(?:#\s*(.*?)\s*$|$)", "# a comment ")
RegexMatch("# a comment ", 1="a comment")

Lors de l'appel à match, vous pouvez éventuellement spécifier l'index auquel commencer la recherche. Par exemple :

Exemple

julia> m = match(r"[0-9]","aaaa1aaaa2aaaa3",1)
RegexMatch("1")

julia> m = match(r"[0-9]","aaaa1aaaa2aaaa3",6)
RegexMatch("2")

julia> m = match(r"[0-9]","aaaa1aaaa2aaaa3",11)
RegexMatch("3")

Vous pouvez extraire les informations suivantes d'un objet RegexMatch :

  • Toute la sous-chaîne correspondante :m.match
  • Les sous-chaînes capturées sous forme de tableau de chaînes :m.captures
  • Le décalage auquel commence la correspondance entière :m.offset
  • Les décalages des sous-chaînes capturées sous forme de vecteur :m.offsets

Lorsqu'une capture ne correspond pas,m.capturesne contient plus de sous-chaîne à cette position, mais ne contient rien ; en outre,m.offsetsle décalage est 0 (rappelez-vous que l'indexation de Julia commence à 1, donc un décalage nul est invalide pour une chaîne). Voici deux exemples quelque peu artificiels :

Exemple

julia> m = match(r"(a|b)(c)?(d)", "acd")
RegexMatch("acd", 1="a", 2="c", 3="d")

julia> m.match
"acd"

julia> m.captures
3-élément Vector{Union{Nothing, SubString{String}}}:
 "a"
 "c"
 "d"

julia> m.offset
1

julia> m.offsets
3-élément Vector{Int64}:
 1
 2
 3

julia> m = match(r"(a|b)(c)?(d)", "ad")
RegexMatch("ad", 1="a", 2=nothing, 3="d")

julia> m.match
"ad"

julia> m.captures
3-élément Vector{Union{Nothing, SubString{String}}}:
 "a"
 nothing
 "d"

julia> m.offset
1

julia> m.offsets
3-élément Vector{Int64}:
 1
 0
 2

Le fait que les captures soient renvoyées sous forme de tableau est pratique, car vous pouvez les lier à des variables locales à l'aide de la syntaxe de déstructuration. Pour plus de commodité, les objets RegexMatch implémentent une méthode d'itération qui délègue au champ captures, de sorte que vous pouvez directement déstructurer l'objet match :

Exemple

julia> first, second, third = m; first
"a"

Il est également possible d'accéder aux captures en indexant l'objet RegexMatch avec le numéro ou le nom du groupe de capture :

Exemple

julia> m=match(r"(?<hour>\d+):(?<minute>\d+)","12:45")
RegexMatch("12:45", hour="12", minute="45")

julia> m[:minute]
"45"

julia> m[2]
"45"

Lors de l'utilisation de replace, vous pouvez référencer les captures dans la chaîne de remplacement en utilisant \n pour faire référence au n-ième groupe de capture et en préfixant la chaîne de remplacement par s. Le groupe de capture 0 fait référence à la correspondance entière. Dans les remplacements, \gpeut être utilisé pour référencer des groupes de capture nommés. Par exemple :

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

Pour plus de clarté, les groupes de capture numérotés peuvent également être référencés avec \gpar exemple :

julia> replace("a", r"." => s"\g<0>1")
"a1"

Vous pouvez modifier une regex en ajoutant des drapeaux tels que i, m, s et x après le guillemet fermant.

Pour en savoir plus sur les expressions régulières, voir :Expressions régulières - Tutoriel

Autres extensions