Programmation en language LUA |
Expressions régulières (Pattern matching) |
Prérequit : Si vous êtes novice en terme de manipulation de chaînes de caractères,
la lecture du document Chaînes et du document Fonctions
des chaînes de caractères est un préalable . Veuillez noter que ce document est une
introduction aux concepts utilisé dans les pattern (modèles) et présente quelques
exemples de la leur utilisation. Ce n'est pas un présentation détaillé des fonctionnalités des pattern.
La bibliothèque de fonction de manipulation des chaîne de caractères de Lua a des fonctionnalité très utile et flexible.
La flexibilité de ces fonctions est due en partie à l'utilisation de pattern (modèles) , parfois (incorrectement) appelées expressions régulières . C'est
une manière d'indiquer un jeu de caractères à rechercher dans
une chaîne de caractères. Dans l'exemple suivant nous recherchons le jeu de caractères 'an'
dans la chaîne de caractères 'banana'
.
La fonction string.find()
renvoie la position de la première
occurrence 'an'
de 'banana'
.
> = string.find('banana ', 'an') -- trouve la 1er occurence
de 'an'
2 3
> = string.find('banana ', 'lua ') -- 'lua 'ne sera pas
trouvé
nil
C'est assez utile mais peu un rigide, par exemple si nous voulons rechercher les mots de quatre lettres qui commencent par "w" :
> text = 'a word to the wise'
> = string.sub(text, string.find(text, 'w...'))
word
> = string.sub(text, string.find(text, 'w...', 5)) -- bit further on...
wise
Dans l'exemple ci-dessus nous employons string.sub()
pour afficher la sous-chaîne que string.find()
a
trouvé. La pattern de recherche que nous avons employé les
deux fois était 'w...'
. Le caractère '.
' représente un
caractère de wildcard, qui peut remplacer n'importe quel
caractère. Les pattern contiennent des séquences de caractères
normaux mais aussi des caractères spéciaux qui ont des significations
spéciales.
Nous définirons une fonction utile pour la suit. Cette fonction prend juste une chaîne de caractères et une pattern et renvoie la sous-chaîne qui correspond au modèle (pattern) dans cette chaîne de caractères :
> function findpattern(text, pattern, start)
>> return string.sub(text, string.find(text, pattern, start))
>> end
>
> = findpattern('a word to the wise', 'w...')
word
> = findpattern('a word to the wise', 'w...', 5)
wise
Une classe de caractère représente un ensemble de caractères. Le caractère wildcard
'.
' peut représenter n'importe quel caractère.
Il y a plusieurs autres classes représentant des sous-ensembles
de caractères, par exemple les nombres, les lettres, caractères majuscules,
minuscules etc... Ces ensembles ont le format %X où X est une lettre représentant la classe. Toutes les
classes de caractère disponibles sont entièrement documentées dans le
manuel de référence de LUA.
Voyons quelques exemples :
> = findpattern('The quick brown fox', '%a') -- %a is all letters
T
> = findpattern('it is 2003', '%d') -- %d finds digits
2
> = findpattern('UPPER lower', '%l') -- %l finds lowercase characters
l
> = findpattern('UPPER lower', '%u') -- %u finds uppercase characters
U
Juste comme nous pouvons rechercher des chaînes de caractères dans les chaînes de caractères , nous pouvons rechercher des séquences de caractères avec les classes de caractère, et nous pouvons mélanger ces derniers à des chaînes de caractères régulières, par exemple,
> = findpattern('UPPERlower', '%u%l') -- upper followed by lower
Rl
> = findpattern('123 234 345', '%d3%d') -- digit 3 digit
234
De lma même façon que nous définissons des classes prédéfinies de caractère, de la forme %X, nous pouvons également explicitement définir nos propres ensembles. Ceux-ci sont représentés comme [ set ] où "set" est une liste de caractères à rechercher.
> = findpattern('banana ', '[ xyjkn ] ') -- recherchez les caractères dans la liste "xyjkn"
n
Employez le trait d'union '-
'pour
dénoter une fourchette des caractères.
> = findpattern('banana ', '[ j-q ] ') -- équivalent au
"jklmnopq"
n
Nous pouvons employer des classes de caractère dans les ensembles :
> = le findpattern('it ist 2003 ', '[ %dabc ] ')
2
Des ensembles peuvent également être employés sous la forme [ ^set ] qui signifie la trouvaille des caractères pas dans l'ensemble énuméré, par exemple,
> = findpattern('banana ', '[ ^ba ] ') -- nous ne
voulons pas a ou b
n
> = les findpattern('bananas, '[ ^a-n ] ') -- ne pas prendre entre a et n
s
> = findpattern('it est 2003 ', '[ ^%l%s ] ') --
pas de lettre minuscule ou espace
2
Parfois nous voulons rechercher des pattern (modèles) mais nous ne connaissons pas le nombre de caractères répété dans la chaîne. Le support de recherche de modèles de longueur variable est possible en
utilisant les caractères : *
+
, -
et ?
. Ceux-ci sont décritsplus en details dans le
manuel de référence LUA aussi nous donnerons un récapitulatif rapide et
quelques exemples ici :
*
recherche 0 répétitions ou plus de l'élément
précédent le modèle, par exemple,
> = findpattern('bananas, 'az * ')
a
> =findpattern('bananas, 'an* ')
an
> = findpattern('bannnnnanas, 'an* ')
annnnnn
+
recherche 1 répétitions ou plus de l'élément
précédent le modèle, par exemple,
> = string.find('banana ', 'az+ ') -- ne seront
pas trouvé
nil
> = findpattern('bananas, 'an+ ')
an
> = findpattern('bannnnnanas, 'de l'an+ ')
annnnn
-
recherche 0 répétitions ou plus de l'élément
précédent le modèle. Mais, ceci diffère de *
qui recherche la séquence la plus courte des éléments, tandis que *
recherche la séquence la plus longue, par exemple,
> = findpattern('bananas, 'az - ')
a
> =
findpattern('bananas, 'an- ')
a
> = findpattern('bannnnanas, 'an- ')
a
?
recherche les occurrences 0 ou 1 de l'élément
précédent de modèle.
> = findpattern('bananas, 'az?')
a
> =
findpattern('bananas, 'an?')
an
> = findpattern('bannnnanas, 'an?')
an
Des captures peuvent être
marquées dans un modèle à l'aide des parenthèses, par exemple, "w(...)"
capturerait les trois dernières lettres du mot de quatre
lettres que nous avons employé dans un exemple précédent :
> = string.find('a word to the wise', 'w(...)') -- last three letters
3 6 ord
> = string.find('a word to the wise', '(w.)(..)') -- two!
3 6 wo rd
> = string.find('a word to the wise', '(w(..).)') -- nested
3 6 word or
Vous pouvez constater que string.find()
renvoie les
index de début et de fin du modèle entier et des captures que nous avons faits à
l'aide des parenthèses dans le modèle.
Ceci peut être très utile en conjonction avec la fonction string.gsub()
, parce qu'au lieu de faire une recherche
simple et remplacement, nous pouvons capturer en rpmier et exécuter le remplacement ensuite, par exemple,
> = string.gsub('a word to the wise', '(t%a+)', 'banana') -- simple replace
a word banana banana wise
2
>
> = string.gsub('a word to the wise', '(t%a+)',
>
> function(x) print(x); return string.upper(x) end)
to
the
a word TO THE wise
2
>
> = string.gsub('a word to the wise', '(w%l+)',
>
> function(x) return '_'..x..'_' end)
a _word_ to the _wise_ 2
www.loriotpro.com |
|