@SergioMaster,CosmoKnacki,Barbibulle
Me permettriez-vous de reprendre tels quels les exemples de cette discussion pour un article sur les expressions régulières ?
Version imprimable
@SergioMaster,CosmoKnacki,Barbibulle
Me permettriez-vous de reprendre tels quels les exemples de cette discussion pour un article sur les expressions régulières ?
:ccool:
Excellente idée.
Sans problème.
J'allais le suggérer , c'est sujet à au moins une FAQ
par contre il faudrait aussi étudier le cas où l'on peut utiliser le Split (un fichier CSV par exemple?)
Meri pour vos réponses. :ccool:
Bonne idée. Il faudrait commencer par regarder ce qu'il y a déjà dans la FAQ, sur les expressions régulières.
Pour la function Split, j'ai complété l'exemple que j'avais déjà posté plus haut dans cette discussion. Il me semble qu'il suffit à faire le tour de la question. Mais il serait intéressant en effet de montrer l'application de cette technique à un fichier CSV.
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 uses RegularExpressions, SysUtils; var a: TArray<string>; s: string; i: integer; begin a := TRegEx.Split(GetEnvironmentVariable('PATH'), ';'); for s in a do WriteLn(s); a := TRegEx.Split('xxx xxx,xxx-xxx', '[ ,-]'); //for s in a do // WriteLn(s); for i := 0 to High(a) do WriteLn(a[i]); ReadLn; end.
Bonjour !
J'ai découvert qu'on pouvait changer la façon dont les groupes sont comptés, et obtenir un résultat que je trouve plus naturel. C'est un peu difficile à expliquer mais en regardant l'exemple vous allez comprendre tout de suite :
Résultat sans l'option "reset" :Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58 program Alternative5; {$APPTYPE CONSOLE} uses SysUtils, RegularExpressions; const SAMPLE: array[0..10] of string = ( '*ABORG-001360', '?CASTELO 1419-002370', '*EX/MINOU1424-412380', '*RUBAN-003001', '1234578011230', '3760162052329', '1456441001360', 'AAAAAAA', '*AAAAA-001', '*AAAAAA001360', '123121212' ); {$DEFINE USE_BRANCH_RESET_GROUP} const PATTERN1 = '^[*?]([^-]{1,15})-(\d{3})(\d{3})$'; PATTERN2 = '^(123\d{10})$'; PATTERN3 = '^(\d{13})$'; {$IFNDEF } PATTERN = PATTERN1 + '|' + PATTERN2 + '|' + PATTERN3; {$ELSE} PATTERN = '(?|' + PATTERN1 + '|' + PATTERN2 + '|' + PATTERN3 + ')'; (* http://www.regular-expressions.info/refadv.html *) {$ENDIF} var g: TGroup; e: TRegEx; m: TMatch; i: integer; begin e := TRegEx.Create(PATTERN); for i := Low(SAMPLE) to High(SAMPLE) do begin m := e.Match(SAMPLE[i]); if m.Success then begin Write(i, ' ', m.Groups.Count); for g in m.Groups do Write(' "', g.Value, '"'); WriteLn; end; end; ReadLn; end.
Avec l'option "reset" :Citation:
0 4 "*ABORG-001360" "ABORG" "001" "360"
1 4 "?CASTELO 1419-002370" "CASTELO 1419" "002" "370"
2 4 "*EX/MINOU1424-412380" "EX/MINOU1424" "412" "380"
3 4 "*RUBAN-003001" "RUBAN" "003" "001"
4 5 "1234578011230" "" "" "" "1234578011230"
5 6 "3760162052329" "" "" "" "" "3760162052329"
6 6 "1456441001360" "" "" "" "" "1456441001360"
Citation:
0 4 "*ABORG-001360" "ABORG" "001" "360"
1 4 "?CASTELO 1419-002370" "CASTELO 1419" "002" "370"
2 4 "*EX/MINOU1424-412380" "EX/MINOU1424" "412" "380"
3 4 "*RUBAN-003001" "RUBAN" "003" "001"
4 2 "1234578011230" "1234578011230"
5 2 "3760162052329" "3760162052329"
6 2 "1456441001360" "1456441001360"
Effectivement si tu n'as pas deux formats nécessitant le même nombre de groupes le "branch reset" peut être une bonne option pour identifier le format utilisé (et ne pas générer de captures vides).
Trucs rigolos avec les branch reset et les captures nommées:
- les noms des captures se transmettent d'une branche à l'autre (quelque soit la branche dans laquelle le nom a été donné), par exemple avec (?|(?<jour>[0-9]{2})/([0-9]{2})|([0-9]{2})\.(?<mois>[0-9]{2})) on peut retrouver les captures en utilisant les noms quelque soit la branche empruntée.
- on peut définir plusieurs groupes de capture avec le même nom dans différentes branches (par défaut utiliser plusieurs fois le même noms pour un groupe est interdit). Il faut toutefois que les groupes avec le même nom soit à la même place (avec le même numéro) dans chaque branche.
Pour pouvoir par exemple intervertir la position de deux groupes nommés, on peut utiliser le modificateur (?J) pour autoriser les noms dupliqués et un groupe non-capturant: (?J)(?:(?<jour>[0-9]{2})/(?<mois>[0-9]{2})|(<mois>[0-9]{2})\.(?<jour>[0-9]{2})) mais dans ce cas magie du branch reset a disparue car si la deuxième branche réussie, les deux groupes de la branche précédente sont créés et débaptisés pour n'avoir que les numéros 1 et 2.(les noms sont données aux vainqueurs, les groupes 3 et 4)