Bibliothèque regex

La bibliothèque regex propose des expressions régulières « classiques », au sens .NET (System.Text.RegularExpressions.Regex), avec la même forme d'API (find/match/gmatch/gsub) que les fonctions de motifs de la bibliothèque string — mais avec une syntaxe et une sémantique différentes. Elle est chargée automatiquement par OpenLibs().

Ne pas confondre avec string : string.find/string.match/... utilisent les motifs Lua (classes %a, %d, ancres ^/$, pas d'alternance | ni de groupes nommés). regex utilise la syntaxe complète des expressions régulières .NET (classes \d, \w, quantificateurs, alternance |, groupes nommés (?<nom>...), lookaround, etc.) — consultez la documentation .NET pour la référence complète de cette syntaxe. Les deux bibliothèques coexistent volontairement séparées pour ne jamais laisser ambiguë la question de savoir dans quel dialecte une chaîne de motif est écrite.

local d, n = regex.match("2026-08-11", [[(\d+)-(\d+)-(\d+)]])
print(d)   --> 2026

for word in regex.gmatch("un deux trois", [[\w+]]) do
    print(word)
end

local s = regex.gsub("hello world", [[o]], "0")
print(s)   --> hell0 w0rld

Vue d'ensemble

Fonction Description
regex.new(pattern [, options]) Compile pattern une fois, retourne un objet regex réutilisable
regex.find(s, pattern [, init [, plain [, options]]]) Position (et captures) du premier match dans s
regex.match(s, pattern [, init [, options]]) Captures (ou le match entier) du premier match dans s
regex.test(s, pattern [, init [, options]]) true/false selon qu'il y a un match
regex.gmatch(s, pattern [, init [, options]]) Itérateur sur tous les matches successifs de pattern dans s
regex.gsub(s, pattern, repl [, n [, options]]) Remplace les occurrences de pattern par repl, retourne le résultat et le nombre de remplacements
regex.split(s, pattern [, options]) Découpe s en tableau selon pattern
regex.escape(s) Échappe les métacaractères regex dans s

Chaînes d'options

Plusieurs fonctions acceptent une chaîne options optionnelle, combinaison des lettres :

Lettre Effet
i Insensible à la casse (IgnoreCase)
m Mode multiligne : ^/$ matchent aussi en début/fin de ligne (Multiline)
s . matche aussi les retours à la ligne (Singleline)
x Espaces/commentaires ignorés dans le motif (IgnorePatternWhitespace)
c Précompile le motif (Compiled)

Une lettre inconnue est une erreur d'argument.

regex.new(pattern [, options])

Compile pattern une fois et retourne un objet regex exposant à la fois les méthodes « saveur Lua » du module (:find/:match/:test/:split/:gmatch/:gsub) et les méthodes .NET natives (:IsMatch/:Match/:Matches/:Replace/:Split/:ToString), pour un script écrit par quelqu'un qui connaît déjà l'API .NET. À préférer aux fonctions du module quand le même motif est réutilisé dans une boucle : les fonctions regex.* recompilent le motif à chaque appel.

local re = regex.new([[\d+]])
print(re:test("abc123"))    --> true
print(re:Match("abc123 def456").Success)   -- via l'API .NET, si exposée par le type Match

Un motif invalide lève une erreur d'argument immédiate (message .NET d'origine).

regex.find(s, pattern [, init [, plain [, options]]])

Cherche la première occurrence de pattern dans s, à partir de la position init (1-based, défaut 1; négative = comptée depuis la fin). Retourne nil si aucune correspondance, sinon les positions de début et de fin (incluse) suivies des captures (ou rien s'il n'y a pas de groupe).

Si plain est vrai, pattern est traité comme une sous-chaîne littérale (recherche simple, pas de regex) — les positions de début/fin sont alors retournées sans capture.

print(regex.find("hello world", [[wor]]))         --> 7  9
print(regex.find("hello (world)", "(", 1, true))  --> 7  7   (recherche littérale du caractère '(')

regex.match(s, pattern [, init [, options]])

Comme regex.find, mais retourne uniquement les captures du premier match (ou le match entier s'il n'y a pas de groupe capturant), sans les positions. Retourne nil en l'absence de match.

regex.test(s, pattern [, init [, options]])

Comme regex.find, mais ne retourne qu'un booléen — plus économique quand seul le fait qu'il y ait correspondance importe (pas de construction de span/captures).

regex.gmatch(s, pattern [, init [, options]])

Retourne un itérateur utilisable avec for qui produit, à chaque appel, les captures du match suivant (ou le match entier sans groupe), jusqu'à épuisement des correspondances dans s :

for k, v in regex.gmatch("a=1, b=2", [[(\w+)=(\d+)]]) do
    print(k, v)
end
--> a  1
--> b  2

regex.gsub(s, pattern, repl [, n [, options]])

Remplace dans s les occurrences de pattern par repl, au plus n fois (illimité par défaut). Retourne la chaîne résultat et le nombre de remplacements effectués. repl peut être :

print(regex.gsub("2026-08-11", [[(\d+)-(\d+)-(\d+)]], "$3/$2/$1"))
--> 11/08/2026  1

print(regex.gsub("hello", [[l]], { l = "L" }))
--> heLLo  2

regex.split(s, pattern [, options])

Découpe s en tableau (indices 1..n) selon les occurrences de pattern. Si pattern contient des groupes capturants, leur contenu est intercalé dans le résultat (comportement de Regex.Split(string) en .NET).

regex.escape(s)

Échappe les métacaractères regex présents dans s, pour l'insérer littéralement dans un motif construit dynamiquement (par exemple à partir d'une entrée utilisateur) :

local needle = regex.escape("a.b*c")
regex.test("a.b*c", needle)   --> true (recherche littérale de "a.b*c")