Précédent   Forum des professionnels en informatique > Logiciels > Solutions d'entreprise > Business Intelligence > SAS > SAS Base
SAS Base Forum d'entraide sur SAS base : étape data, procédures non statistiques, procédures non graphiques, SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 02/05/2011, 15h05   #1
Membre éclairé
 
Homme
statisticien
Inscription : mai 2011
Messages : 212
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : statisticien
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : mai 2011
Messages : 212
Points : 319
Points : 319
Par défaut PRXPARSE/PRXCHANGE : Expressions régulières dans SAS ???

Bonjour,

je travaille dans le géo-référencement et afin d'améliorer la qualité je veux exploiter les informations contenues dans les compléments d'adresses afin de les nettoyer et d'extraires des informations qui pourront être utiles.

Par exemble pour un individu ayant mis en complément d'adresse
" BATIMENT FOCH 3EME ETG PORTE 1200"
je ne souhaiterais garder que "BATIMENT FOCH".
Tout ça c'est théorique biensur , la réalité est plus compliquée...

Donc pour réaliser ce nettoyage et cette normalisation j'utilise les expressions régulières de SAS : PRXPARSE et CALL PRXCHANGE

Mais cela ne semble pas marcher comme je le souhaite...

Voici un bout de mon code avec un exemple

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
DATA batiment;
input string $46.;
DATALINES;
BATIMENT C
PRTE 76 BATIMENT 2 ETG 4
BATIMENT 2A ESC C APPT 275
BATIMENT 3C
LES ODALIES BATIMENT 3300
BATIMENT 45F
 ;
 run;
 
 DATA batiment; SET batiment;
 length string2 num capture $46.;
 
 IF _N_=1 then 
do;
call prxdebug(1);
retain  ch_BATIMENT ch_BATIMENT2 ch_CAPTURE;
ch_BATIMENT=
prxparse("s/(.{0,46}?)(\sBATIMENT\s?)([0-9A-Z][0-9A-Z]?[0-9]{0,2}?\s)(.{0,46}?)/$1 $4/");
ch_BATIMENT2=
prxparse("s/(.{0,46}?)(\sBATIMENT\s?)([0-9A-Z][0-9A-Z]?[0-9]{0,2}?\s)(.{0,46}?)/$3/");
ch_CAPTURE=
prxparse("s/(.{0,46}?)(\sBATIMENT\s?)([0-9A-Z][0-9A-Z]?[0-9]{0,2}?\s)(.{0,46}?)/$1w$2w$3w$4/");
call prxdebug(0);
end;
string=" "!!string;
call prxchange(ch_BATIMENT2,-1,string,num);
call prxchange(ch_BATIMENT,-1,string,string2);
call prxchange(ch_CAPTURE,-1,string,capture);
run;
 
proc print DATA=batiment;
var string;run;
 
proc print DATA=batiment;
var string2;run;
 
proc print DATA=batiment;
var num;run;
 
proc print DATA=batiment;
var capture;run;

et voici ce que j'obtiens

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
 
                               Obs    string
 
                                1     BATIMENT C
                                2     PRTE 76 BATIMENT 2 ETG 4
                                3     BATIMENT 2A ESC C APPT 275
                                4     BATIMENT 3C
                                5     LES ODALIES BATIMENT 3300
                                6     BATIMENT 45F
 
 
                                     Obs       string2
 
                                      1
                                      2     PRTE 76 ETG 4
                                      3     ESC C APPT 275
                                      4
                                      5     LES ODALIES
                                      6     BATIMENT 45F
 
                                   Obs           num
 
                                    1     C
                                    2     2 ETG 4
                                    3     2A ESC C APPT 275
                                    4     3C
                                    5     3300
                                    6      BATIMENT 45F
 
                             Obs    capture
 
                              1     w BATIMENT wC w
                              2      PRTE 76w BATIMENT w2 wETG 4
                              3     w BATIMENT w2A wESC C APPT 275
                              4     w BATIMENT w3C w
                              5      LES ODALIESw BATIMENT w3300 w
                              6      BATIMENT 45F
string est la variable à nettoyer

string2 est la variable nettoyée (c'est à dire tout ce qui peut ressemble à "BATIMENT + numero de batiment doit être enlevé de la chaine)

num est la variable censée récuperer le numero de batiment

et capture donne une idée ce qui est contenu dans les buffer de capture (du moins je pense, séparée par des w minuscules

Pour les observations 1 4 et 5 tout se passe normalement.
Pour l'observation 6 le batiment + numero de batiment n'est pas reconnu ce qui était prévu à l'écriture, j'ai délibérement souhaité reconnaitre des batiments "simples" dans un premier temps style batiment "B1" ou "2C" et par 45F ou "FOCH" etc...

Par contre pour les observations 2 et 3 si le nettoyage (string2) se passe tout a fait comme attendu, la récupération du numero de batiment ne se passe pas bien du tout puisque je récupère "2 ETG 4" à la place de "2" et "2A ESC C APPT 27" à la place de "2A" ...

Et là je ne comprend plus du tout ce que je pensais avoir compris du fonctionnement des expressions régulières dans SAS , sachant que je m'y suis mis depuis peu.

Est-ce un bug ou est-ce moi qui m'y prend mal dans la rédaction de mon code ? Pourriez-vous m'indiquer ce qui ne marche pas et comment y remédier ?

Voici la log au besoin

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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
4770   DATA batiment; SET batiment;
4771   length string2 num capture $46.;
4772
4773   IF _N_=1 then
4774  do;
4775  call prxdebug(1);
4776  retain  ch_BATIMENT ch_BATIMENT2 ch_CAPTURE;
4777  ch_BATIMENT=
4778  prxparse("s/(.{0,46}?)(\sBATIMENT\s?)([0-9A-Z][0-9A-Z]?[0-9]{0,2}?\s)(.{0,46}?)/$1 $4/");
4779  ch_BATIMENT2=
4780  prxparse("s/(.{0,46}?)(\sBATIMENT\s?)([0-9A-Z][0-9A-Z]?[0-9]{0,2}?\s)(.{0,46}?)/$3/");
4781  ch_CAPTURE=
4782  prxparse("s/(.{0,46}?)(\sBATIMENT\s?)([0-9A-Z][0-9A-Z]?[0-9]{0,2}?\s)(.{0,46}?)/$1w$2w$3w
4782! $4/");
4783  call prxdebug(0);
4784  end;
4785  string=" "!!string;
4786  call prxchange(ch_BATIMENT2,-1,string,num);
4787  call prxchange(ch_BATIMENT,-1,string,string2);
4788  call prxchange(ch_CAPTURE,-1,string,capture);
4789  run;
 
Compiling REx `(.{0,46}?)(\sBATIMENT\s?)([0-9A-Z][0-9A-Z]?[0-9]{0,2}?\s)(.{0,46}?)'
size 65 first at 4
rarest char B at 0
   1: OPEN1(3)
   3:   MINMOD(4)
   4:   CURLY {0,46}(7)
   6:     REG_ANY(0)
   7: CLOSE1(9)
   9: OPEN2(11)
  11:   SPACE(12)
  12:   EXACT <BATIMENT>(15)
  15:   CURLY {0,1}(18)
  17:     SPACE(0)
  18: CLOSE2(20)
  20: OPEN3(22)
  22:   ANYOF[0-9A-Z](31)
  31:   CURLY {0,1}(42)
  33:     ANYOF[0-9A-Z](0)
  42:   MINMOD(43)
  43:   CURLY {0,2}(54)
  45:     ANYOF[0-9](0)
  54:   SPACE(55)
  55: CLOSE3(57)
  57: OPEN4(59)
  59:   MINMOD(60)
  60:   CURLY {0,46}(63)
  62:     REG_ANY(0)
  63: CLOSE4(65)
  65: END(0)
floating `BATIMENT' at 1..47 (checking floating) minlen 11
 
Compiling REx `(.{0,46}?)(\sBATIMENT\s?)([0-9A-Z][0-9A-Z]?[0-9]{0,2}?\s)(.{0,46}?)'
size 65 first at 4
rarest char B at 0
   1: OPEN1(3)
   3:   MINMOD(4)
   4:   CURLY {0,46}(7)
   6:     REG_ANY(0)
   7: CLOSE1(9)
   9: OPEN2(11)
  11:   SPACE(12)
  12:   EXACT <BATIMENT>(15)
  15:   CURLY {0,1}(18)
  17:     SPACE(0)
  18: CLOSE2(20)
  20: OPEN3(22)
  22:   ANYOF[0-9A-Z](31)
  31:   CURLY {0,1}(42)
  33:     ANYOF[0-9A-Z](0)
  42:   MINMOD(43)
  43:   CURLY {0,2}(54)
  45:     ANYOF[0-9](0)
  54:   SPACE(55)
  55: CLOSE3(57)
  57: OPEN4(59)
  59:   MINMOD(60)
  60:   CURLY {0,46}(63)
  62:     REG_ANY(0)
  63: CLOSE4(65)
  65: END(0)
floating `BATIMENT' at 1..47 (checking floating) minlen 11
 
Compiling REx `(.{0,46}?)(\sBATIMENT\s?)([0-9A-Z][0-9A-Z]?[0-9]{0,2}?\s)(.{0,46}?)'
size 65 first at 4
rarest char B at 0
   1: OPEN1(3)
   3:   MINMOD(4)
   4:   CURLY {0,46}(7)
   6:     REG_ANY(0)
   7: CLOSE1(9)
   9: OPEN2(11)
  11:   SPACE(12)
  12:   EXACT <BATIMENT>(15)
  15:   CURLY {0,1}(18)
  17:     SPACE(0)
  18: CLOSE2(20)
  20: OPEN3(22)
  22:   ANYOF[0-9A-Z](31)
  31:   CURLY {0,1}(42)
  33:     ANYOF[0-9A-Z](0)
  42:   MINMOD(43)
  43:   CURLY {0,2}(54)
  45:     ANYOF[0-9](0)
  54:   SPACE(55)
  55: CLOSE3(57)
  57: OPEN4(59)
  59:   MINMOD(60)
  60:   CURLY {0,46}(63)
  62:     REG_ANY(0)
  63: CLOSE4(65)
  65: END(0)
floating `BATIMENT' at 1..47 (checking floating) minlen 11
 
NOTE: There were 6 observations READ FROM the DATA SET WORK.BATIMENT.
NOTE: The DATA SET WORK.BATIMENT has 6 observations AND 7 VARIABLES.
NOTE: DATA statement used (Total process time):
      real time           0.01 seconds
      cpu time            0.01 seconds
Merci.
jerome_pdv2 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/05/2011, 15h34   #2
Modérateur
 
Homme Samir SELMANE
Consultant en Business Intelligence
Inscription : février 2011
Messages : 1 006
Détails du profil
Informations personnelles :
Nom : Homme Samir SELMANE
Localisation : France

Informations professionnelles :
Activité : Consultant en Business Intelligence
Secteur : Conseil

Informations forums :
Inscription : février 2011
Messages : 1 006
Points : 1 703
Points : 1 703
Bonjour;

t'as regardé ici et quelques détails ici

Remarque: les expressions régulière ne sont pas natives à SAS.
s_a_m est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/05/2011, 15h48   #3
Membre éclairé
 
Homme
statisticien
Inscription : mai 2011
Messages : 212
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : statisticien
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : mai 2011
Messages : 212
Points : 319
Points : 319
Bonjour

Citation:
Envoyé par s_a_m Voir le message
Bonjour;

t'as regardé ici .

alors là oui, je ne savais pas que ça marchait aussi comme ça, mais il me semble que ça ne me donne pas vraiment d'éléments pour la résolution de mon problème... :/

Citation:
Envoyé par s_a_m Voir le message
et quelques détails ici .


J'y ai bien jeté un oeil, je regarde ça depuis la semaine passée en fait, toujours un peu difficile l'anglais pour moi ^^ , mais je n'ai rien trouvé qui puisse m'expliquer vraiment ce qu'il se passe dans mon problème actuel.
C'est à partir de cette note que j'ai écris en grande partie mon code SAS avec des expressions régulières.
Citation:
Envoyé par s_a_m Voir le message
Remarque: les expressions régulière ne sont pas natives à SAS.
OUI... Je sais... mais en l'occurence je travaille sous SAS uniquement



EDIT :

J'ai résolu partiellement mon problème, enfin il est résolu, mais je met partiellement, car il y a quelque chose que je ne comprend pas dans l'appel de la fonction prxchange.

J'ai contourné mon problème en combinant prxmatch et prxposn qui me donnent finalement le résultat attendu.

voici mon code modifié

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
 
DATA batiment;
input string $46.;
DATALINES;
BATIMENT C
PRTE 76 BATIMENT 2 ETG 4
BATIMENT 2A ESC C APPT 275
BATIMENT 3C
LES ODALIES BATIMENT 3300
BATIMENT 45F
 ;
 run;
 
 DATA batiment; SET batiment;
 length string2 num capture num_bis string3 $46.;
 
 IF _N_=1 then 
do;
call prxdebug(1);
retain  ch_BATIMENT  ch_BATIMENT2 ch_BATIMENT3 ch_CAPTURE ch_NUMBAT;
ch_NUMBAT=
prxparse("/(.{0,46}?)(\sBATIMENT\s?)([0-9A-Z][0-9A-Z]?[0-9]{0,2}?\s)(.{0,46}?)/");
ch_BATIMENT=
prxparse("s/(.{0,46}?)(\sBATIMENT\s?)([0-9A-Z][0-9A-Z]?[0-9]{0,2}?\s)(.{0,46}?)/$1 $4/");
ch_BATIMENT2=
prxparse("s/(.{0,46}?)(\sBATIMENT\s?)([0-9A-Z][0-9A-Z]?[0-9]{0,2}?\s)(.{0,46}?)/$3/");
ch_BATIMENT3=
prxparse("s/(.{0,46}?)(\sBATIMENT\s?)([0-9A-Z][0-9A-Z]?[0-9]{0,2}?\s)(.{0,46}?)/$3 $4/");
ch_CAPTURE=
prxparse("s/(.{0,46}?)(\sBATIMENT\s?)([0-9A-Z][0-9A-Z]?[0-9]{0,2}?\s)(.{0,46}?)/$1w$2w$3w$4/");
call prxdebug(0);
end;
string=" "!!string;
call prxchange(ch_BATIMENT3,-1,string,string3);
call prxchange(ch_BATIMENT2,-1,string,num);
call prxchange(ch_BATIMENT,-1,string,string2);
call prxchange(ch_CAPTURE,-1,string,capture);
IF prxmatch(ch_numbat,string) then num_bis=prxposn(ch_NUMBAT,3,string);
run;
 
proc print DATA=batiment;
var string;run;
 
proc print DATA=batiment;
var string2;run;
 
proc print DATA=batiment;
var num;run;
 
proc print DATA=batiment;
var capture;run;
 
proc print DATA=batiment;
var num_bis;run;
 
proc print DATA=batiment;
var string3;run;
voici la sortie pour les variables num_bis (la variable que je voulais avoir) et string3 qui dans mon exemple correspond à ce que je récupère aussi dans num mais avec un code différent

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
                                        Obs    num_bis
 
                                         1      C
                                         2      2
                                         3      2A
                                         4      3C
                                         5      3300
                                         6
 
 
                                   Obs         string3
 
                                    1     C
                                    2     2  ETG 4
                                    3     2A  ESC C APPT 275
                                    4     3C
                                    5     3300
                                    6      BATIMENT 45F
string3 et num sont semblables alors qu'issues de formes régulières différentes ..... respectivement ch_BATIMENT2 pour num et ch_BATIMENT3 pour string3

Code :
1
2
3
4
ch_BATIMENT2=
prxparse("s/(.{0,46}?)(\sBATIMENT\s?)([0-9A-Z][0-9A-Z]?[0-9]{0,2}?\s)(.{0,46}?)/$3/");
ch_BATIMENT3=
prxparse("s/(.{0,46}?)(\sBATIMENT\s?)([0-9A-Z][0-9A-Z]?[0-9]{0,2}?\s)(.{0,46}?)/$3 $4/");
Je laisse en non résolu pendant quelques jours au cas ou quelqu'un pourrait m'expliquer le pourquoi du problème dans ma définition de la forme régulière ch_BATIMENT2 , car cela montre que je n'ai pas encore tout compris comment fonctionne prxparse et/ou prxchange
et pour finir par une boutade parce que je n'aimerais pas mourrir idiot...

Merci à tous.

Concernant les formes régulières sous SAS , il y a cette petite synthèse basique fort utile à avoir sous la main.

http://support.sas.com/rnd/base/data...-tip-sheet.pdf
jerome_pdv2 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/05/2011, 16h53   #4
Membre du Club
 
Homme Fabien
Inscription : novembre 2008
Messages : 59
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Localisation : France

Informations forums :
Inscription : novembre 2008
Messages : 59
Points : 56
Points : 56
Salut,

J'ai peut etre pas tout compris ce que tu cherches à faire mais le code ci dessous recupere le 'truc' apres BATIMENT.

Code :
1
2
3
4
5
DATA aa;
	SET batiment;
t=prxchange("s/(.*(BATIMENT))//",-1,string);
t1 = scan(t,1,' ');
run;
Suitrop
suistrop est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/05/2011, 17h11   #5
Membre éclairé
 
Homme
statisticien
Inscription : mai 2011
Messages : 212
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : statisticien
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : mai 2011
Messages : 212
Points : 319
Points : 319
oui je cherche a récupérer le truc après BATIMENT MAIS afin de ne pas récupérer tout et n'importe quoi je veux que ça ai un "sens" dans un premier temps, car c'est essentiel pour faire un bon nettoyage.

Et donc je cherche a faire ça à la seule condition que cela "ressemble" à quelque chose qui peut vraisemblablement être un numéro de bâtiment comme :
"5" "A" "B2" "2C" "1200" mais je ne désire pas récupérer "DROITE" dans "BATIMENT DROITE" ou "FOND" dans "BATIMENT FOND DE COUR" ou "SOL" de "BATIMENT SOL" et non plus "LE" de "BATIMENT LE FLOREAL" auquel je n'ai pas encore pensé ceci dit en passant...(enfin presque...)

C'est pourquoi j'ai défini le motif "[0-9A-Z][0-9A-Z]?[0-9]{0,2}?\s)" correspondant à ce à quoi doit ressembler le numéro du bâtiment( c'est à dire si j'ai bien tout compris) $3.
Si ça correspond pas, je laisse et je m'en occupe plus tard.
Je nettoie par étape, car on rencontre vraiment tout et n'importe quoi dans le complément d'adresse, donc voilà pour répondre a ton interrogation, ton code marche sans doute mais je veux qu'il respecte une certaine contrainte sinon on ne doit rien faire et on passe aux étapes suivantes du nettoyage par exemple récupérer le numéro de porte ou de logement, puis l'escalier etc...

Par contre ton exemple viens de me faire réaliser comment fonctionnait un peu prxchange, par contre cela ne m'explique pas pourquoi ces deux expressions régulières conduisent au même résultat

Code :
1
2
3
4
5
 
ch_BATIMENT2=
prxparse("s/(.{0,46}?)(\sBATIMENT\s?)([0-9A-Z][0-9A-Z]?[0-9]{0,2}?\s)(.{0,46}?)/$3/");
ch_BATIMENT3=
prxparse("s/(.{0,46}?)(\sBATIMENT\s?)([0-9A-Z][0-9A-Z]?[0-9]{0,2}?\s)(.{0,46}?)/$3 $4/");
jerome_pdv2 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/05/2011, 18h00   #6
Modérateur
 
Homme Samir SELMANE
Consultant en Business Intelligence
Inscription : février 2011
Messages : 1 006
Détails du profil
Informations personnelles :
Nom : Homme Samir SELMANE
Localisation : France

Informations professionnelles :
Activité : Consultant en Business Intelligence
Secteur : Conseil

Informations forums :
Inscription : février 2011
Messages : 1 006
Points : 1 703
Points : 1 703
Citation:
Envoyé par jerome_pdv2 Voir le message
Et donc je cherche a faire ça à la seule condition que cela "ressemble" à quelque chose qui peut vraissemblablement être un numéro de batiment comme :
"5" "A" "B2" "2C" "1200" mais je ne désire pas récupérer "DROITE" dans "BATIMENT DROITE" ou "FOND" dans "BATIMENT FOND DE COUR" ou "SOL" de "BATIMENT SOL" et non plus "LE" de "BATIMENT LE FLOREAL" auquel je n'ai pas encore pensé ceci dit en passant...(enfin presque...)
Oh , sa me rappel les SIG tout sa.

Tu n'as pas une table ou un fichier où tu pourras récupérer les valeurs possibles du numéro de bâtiment? L’idée que j’imagine est :
1-de faire une condition si le résultat renvoyé par les expressions regu appartient à cette liste donc à garder sinon à nettoyer. (Bien sûre si tu ne les a pas quelque part dans une table ou dans fichiers tu ne va pas les saisir à la main).

Si tu les as alors tu pourras les récupérer dans une macro variable avec une call symput et faire boucle avec condition comme dans 1.

Le problème qui se pose dans ton cas c’est comment faire la distinction entre ce qu’il faut garder et ce qu’il supprimer /zapper. Il y a-t-il un critère particulier ?
Sa sera difficile de proposer une solution puisqu’on ne connaît pas les valeurs possibles du numéro de bâtiment.
Avec un peu plus de détails on/t’y arrivera.
s_a_m est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/05/2011, 18h43   #7
Membre éclairé
 
Homme
statisticien
Inscription : mai 2011
Messages : 212
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : statisticien
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : mai 2011
Messages : 212
Points : 319
Points : 319
Pour ton 1- , la liste quelque part c'est un peu ce que je cherche à faire et je ne peux pas en faire une à la main vu que je suis sur des tables france entière avec 50 millions d'individus
Donc je suis obligé d'y aller à l'aveugle, de repérer les cas "classiques" de les traiter, et ensuite revenir sur les moins "classiques", les traiter, et regarder ce que je peux récupérer encore, après je fais de la stat donc a un certain niveau de récupération lorsque les cas seront trop tordus et rares je laisserais tomber


Mon critère actuel ici c'est (Lettre ou chiffre) + (peut etre encore une lettre ou chiffre) + (éventuellement encore deux chiffres) suivi d'un blanc soit
[0-9A-Z][0-9A-Z]?[0-9]{0,2}?\s

Pour le code j'ai trouvé, j'ai fait légèrement autrement

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
 
 
DATA batiment;
 IF _N_=1 then 
do;
retain  ch_NUMBAT;
ch_NUMBAT=
prxparse("/(.{0,46}?)(\sBATIMENT\s?)([0-9A-Z][0-9A-Z]?[0-9]{0,2}?\s)(.{0,46}?)/");
end;
DROP ch_NUMBAT;
input string $46.;
length num $46.;string=" "!!string;
IF prxmatch(ch_NUMBAT,string) 
then 
num=prxposn(ch_NUMBAT,3,string);
DATALINES;
BATIMENT C
PRTE 76 BATIMENT 2 ETG 4
BATIMENT 2A ESC C APPT 275
BATIMENT 3C
LES ODALIES BATIMENT 3300
BATIMENT 45F
;
run;
Donc mon problème de stricte récupération de la variable est résolu,

je continue ce fil parce ce que je ne comprend pas pourquoi ce code ci-dessus marche,
alors que celui ci-dessous ne marche pas !!

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 
DATA batiment;
 IF _N_=1 then 
do;
retain  ch_BATIMENT2;
ch_BATIMENT2=
prxparse("s/(.{0,46}?)(\sBATIMENT\s?)([0-9A-Z][0-9A-Z]?[0-9]{0,2}?\s)(.{0,46}?)/$3/");
end;
DROP ch_BATIMENT2;
input string $46.;
length num $46.;string=" "!!string; 
num=prxchange(ch_BATIMENT2,-1,string);
DATALINES;
BATIMENT C
PRTE 76 BATIMENT 2 ETG 4
BATIMENT 2A ESC C APPT 275
BATIMENT 3C
LES ODALIES BATIMENT 3300
BATIMENT 45F
;
run;
Alors que c'est pour moi la même chose, et je ne comprend pas d'où viens le problème...

A ce stade, sans autres explications je le prend pour un BUG de SAS.... ???

voili voilou

Si quelqu'un a une idée....
jerome_pdv2 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/05/2011, 20h09   #8
Membre éclairé
 
Homme
statisticien
Inscription : mai 2011
Messages : 212
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : statisticien
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : mai 2011
Messages : 212
Points : 319
Points : 319
Problème résolu, c'était un problème de définition de l'expression régulière j'avais mis des ? en redondance (ceux en rouge).... :/


ch_BATIMENT2=
prxparse("s/(.{0,46}?)(\sBATIMENT\s?)([0-9A-Z][0-9A-Z]?[0-9]{0,2}?\s)(.{0,46}?)/$3/");

En les supprimant cela marche sans problème comme attendu..... !!!

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
 
DATA batiment;
 IF _N_=1 then 
do;
retain  ch_BATIMENT2;
ch_BATIMENT2=
prxparse("s/(.{0,46})(\sBATIMENT\s?)([0-9A-Z][0-9A-Z]?[0-9]{0,2}\s)(.{0,46})/$3/");
end;
DROP ch_BATIMENT2;
input string $46.;
length num $46.;string=" "!!string; 
IF prxmatch(ch_BATIMENT2,string) then num=prxchange(ch_BATIMENT2,-1,string);
DATALINES;
BATIMENT C
PRTE 76 BATIMENT 2 ETG 4
BATIMENT 2A ESC C APPT 275
BATIMENT 3C
LES ODALIES BATIMENT 3300
BATIMENT 45F
;
run;
proc print DATA=batiment;run;
 
                           Obs    string                        num
 
                            1     BATIMENT C                    C
                            2     PRTE 76 BATIMENT 2 ETG 4      2
                            3     BATIMENT 2A ESC C APPT 275    2A
                            4     BATIMENT 3C                   3C
                            5     LES ODALIES BATIMENT 3300     3300
                            6     BATIMENT 45F
Le problème est résolu, c'était un problème de spécification de la forme régulière qui du coup devait pas bien fonctionner...
jerome_pdv2 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/05/2011, 17h36   #9
Membre confirmé
 
Inscription : janvier 2010
Messages : 185
Détails du profil
Informations forums :
Inscription : janvier 2010
Messages : 185
Points : 250
Points : 250
Bonjour jerome_pdv2,


Je me permets de porter une critique que j'espère constructive à ton utilisation des expressions régulières :
Code :
s/(.{0,46})(\sBATIMENT\s?)([0-9A-Z][0-9A-Z]?[0-9]{0,2}\s)(.{0,46})/$3/
D'abord, tu fais une utilisation un peu tirée par les cheveux de l'écriture s/// qui sert avant tout à faire de la substitution de chaine.
Ici tu substitues le tout (l'adresse complète) par la partie (le numéro du batiment).
Cela revient en fait à récupérer le numéro du batiment et t'oblige à décrire de façon fastidieuse l'intégralité de ta chaine
en utilisant l'astuce de commencer et de finir ta regexp par .{0,46}.

Donc en utilisant une regexp de type // au lieu de s/// les 2 sous-chaines .{0,46} deviennent superflues et ton expression devient :
Code :
/(\sBATIMENT\s?)([0-9A-Z][0-9A-Z]?[0-9]{0,2}\s)/
Ensuite tu utilises trop de buffer de captures : les parenthèses.
Ce qui t'intéresse c'est le numéro du batiment, çad [0-9A-Z][0-9A-Z]?[0-9]{0,2}\s.
Donc contentons nous de placer des parenthèses autour de ce seul numéro.
Cela libérera de la mémoire et du temps de traitement.

On obtient:

Code :
/BATIMENT\s?([0-9A-Z][0-9A-Z]?[0-9]{0,2}\s)/

Maintenant que tu as un unique buffer $1, il te faut le récuperer grace à la fonction prxposn :

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
 
 
DATA batiment;
retain  reg ;
IF _N_=1 then do;
	reg=prxparse("/BATIMENT\s?([0-9A-Z][0-9A-Z]?[0-9]{0,2}\s)/");
end;
input string $46.;
length num $46.; 
IF  prxmatch(reg, string) then do;
	num=prxposn(reg, 1, string);
end;	
DROP reg ;
RETURN;
DATALINES;
BATIMENT C
PRTE 76 BATIMENT 2 ETG 4
BATIMENT 2A ESC C APPT 275
BATIMENT 3C
LES ODALIES BATIMENT 3300
BATIMENT 45F
;
run;
proc print DATA=batiment;run;
Voilà. On pourrait revoir l'expression du numéro [0-9A-Z][0-9A-Z]?[0-9]{0,2}\s pour capter le 45F par exemple mais si ça
te suffit je vais en rester là. On a déjà gagné en lisibilité et en efficacité.
sasadm est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 03/05/2011, 18h03   #10
Membre éclairé
 
Homme
statisticien
Inscription : mai 2011
Messages : 212
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : statisticien
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : mai 2011
Messages : 212
Points : 319
Points : 319
Bonjour et merci de ta critique constructive... (d'ailleurs j'écris rarement de façon optimale lol)

mais enfin... je n'ai pas que le seul but du numéro...

Je veux récupérer le numéro de batiment effectivement, mais je veux aussi "nettoyer" mon complément d'adresse

par exemple j'ai un complément d'adresse comme ceci :

COMPLEMENT ="BLABLABLA1 BATIMENT 2 BLABLABLA2"

Je veux avoir en sortie :

1 - Le numéro de bâtiment effectivement BATIMENT='2'

mais aussi

2 - le complément d'adresse nettoyé en

COMPLEMENT_NETTOYE="BLABLABLA1 BLABLABLA2"

Que je vais ensuite explorer de nouveau pour trouver des choses signifiantes (numero de logement, d'etage, d'escalier etc...)

donc si ma forme régulière à cette forme c'est parce que j'utilise aussi les buffer de capture 1 et 4 pour construire le complément nettoyé...

voici le code complet

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
 
DATA batiment;
length string string_nettoye $46. num $5.;
 IF _N_=1 then 
do;
retain  ch_BATIMENT2 ch_BATIMENT1;
ch_BATIMENT2=
prxparse("s/(.{0,46})(\sBATIMENT\s?)([0-9A-Z][0-9A-Z]?[0-9]{0,2}\s)(.{0,46})/$3/");
ch_BATIMENT1=
prxparse("s/(.{0,46})(\sBATIMENT\s?)([0-9A-Z][0-9A-Z]?[0-9]{0,2}\s)(.{0,46})/$1 $4/");
end;
DROP ch_BATIMENT2 ch_BATIMENT1;
input string $46.;
string=" "!!string; 
IF prxmatch(ch_BATIMENT2,string) then num=prxchange(ch_BATIMENT2,-1,string);
call prxchange (ch_BATIMENT1,-1,string,string_nettoye);
DATALINES;
BATIMENT C
PRTE 76 BATIMENT 2 ETG 4
BATIMENT 2A ESC C APPT 275
BATIMENT 3C
LES ODALIES BATIMENT 3300
BATIMENT 45F
;
run;
proc print DATA=batiment;run;
et le résultat avec les DEUX variables attendues

num pour le numero de bâtiment extrait

ET

string_nettoye pour la chaine nettoyée de BATIMENT + numero de bâtiment



Code :
1
2
3
4
5
6
7
8
9
 
                  Obs    string                        string_nettoye    num
 
                   1     BATIMENT C                                      C
                   2     PRTE 76 BATIMENT 2 ETG 4      PRTE 76 ETG 4     2
                   3     BATIMENT 2A ESC C APPT 275    ESC C APPT 275    2A
                   4     BATIMENT 3C                                     3C
                   5     LES ODALIES BATIMENT 3300     LES ODALIES       3300
                   6     BATIMENT 45F                  BATIMENT 45F
Pour le BATIMENT 45F je veux que ça reste comme ça, un F en troisième position pour un numéro de bâtiment à ce stade là je considère ça comme suspect et surtout je peux capter autre chose dans d'autres cas que je ne voudrais pas dans un premier temps et je veux rester "simple".

Donc effectivement pour récupérer le numéro de batiment, je peux faire la modification que tu suggère ce sera effectivement plus simple j'avoue.
Mais en fait j'avais juste repris le motif du nettoyage présent dans ch_BATIMENT pour ch_BATIMENT2

Et en fait j'aimerais bien déclarer une seule et même forme régulière pour faire les deux opérations... ce qui serait sans doute plus économique...

car dans une dernière modification mes formes régulières sont devenues...

Code :
1
2
ch_BATIMENT=prxparse("s/(.{0,46})(\sBATIMENT\s?)(([A-Z][0-9]?|[0-9]{1,2}|[0-9][A-Z]?)[0-9]{0,2}\s)(.{0,46})/$1 $8/");
ch_BATIMENT2=prxparse("s/(.{0,46})(\sBATIMENT\s?)(([A-Z][0-9]?|[0-9]{1,2}|[0-9][A-Z]?)[0-9]{0,2}\s)(.{0,46})/$3/");




Edit :

Du coup j'ai fait la chose avec une seule forme régulière et deux scan puis supprimé le buffer pour " BATIMENT"

Peut-être est ce que cela utilisera moins de ressources comme ceci...

De plus j'ai modifié mes formes {0,46} par la forme plus générale .* il semble que SAS la digère mieux ...

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
 
 
DATA batiment;
length string string_nettoye $46. num $5. intermediaire $47.;
 IF _N_=1 then 
do;
retain   ch_BATIMENT;
ch_BATIMENT=
prxparse("s/(.*)\sBATIMENT\s?([0-9A-Z][0-9A-Z]?[0-9]{0,2}\s)(.*)/$1 $3+$2/");
 
end;
DROP ch_BATIMENT intermediaire;
input string $46.;
string=" "!!string; 
call prxchange(ch_BATIMENT,-1,string,intermediaire);
num=scan(intermediaire,2,'+');
string_nettoye=scan(intermediaire,1,'+');
DATALINES;
BATIMENT C
PRTE 76 BATIMENT 2 ETG 4
BATIMENT 2A ESC C APPT 275
BATIMENT 3C
LES ODALIES BATIMENT 3300
BATIMENT 45F
;
run;
proc print DATA=batiment;run;

Re-Edit : selon toi je devrais plutôt privilieger l'utilisation de prxmatch, et 3 prxposn et de l'expression // à la place d'un prxchange,de l'expression s/// et de deux scan ?
jerome_pdv2 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/05/2011, 11h48   #11
Membre confirmé
 
Inscription : janvier 2010
Messages : 185
Détails du profil
Informations forums :
Inscription : janvier 2010
Messages : 185
Points : 250
Points : 250
Bonjour

ça m'apprendra à lire tous les messages

Voici ce que je te propose :
  1. limiter le lancement du bousin aux seules adresses qui contiennent BATIMENT => gain de ressource et de temps car les fonctions perl sont consommatrices.
  2. garder le s/// mais à l'inverse de ta démarche, effacer le mot batiment et son numero => pas besoin d'étapes supplementaires


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
DATA batiment;
length string string_nettoye $46. pos  4  num $5. ;
retain ch_BATIMENT;
IF _N_=1 then ch_BATIMENT=prxparse("s/BATIMENT\s?([0-9A-Z][0-9A-Z]?[0-9]{0,2}\s)//");
input string $46.;
 
/* lancement des traitements "perl" si BATIMENT => gain de ressource */
IF INDEX(string, "BATIMENT") THEN DO;
 
	/* test du matching BATIMENT + numero */
	pos=prxmatch(ch_BATIMENT, string);
	/* si test OK */
	IF pos  then do;
		/* recuperation du numero */
		num=prxposn(ch_BATIMENT, 1, string);
		/* recuperation de la chaine nettoyee */
		call prxchange(ch_BATIMENT, 1, string, string_nettoye);
	end;
END; 
 
KEEP string  num string_nettoye;
DATALINES;
IMMEUBLE 2
BATIMENT C
PRTE 76 BATIMENT 2 ETG 4
BATIMENT 2A ESC C APPT 275
BATIMENT 3C
LES ODALIES BATIMENT 3300
BATIMENT 45F
;
run;
proc print DATA=batiment;run;
sasadm est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/05/2011, 12h21   #12
Membre éclairé
 
Homme
statisticien
Inscription : mai 2011
Messages : 212
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : statisticien
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : mai 2011
Messages : 212
Points : 319
Points : 319
ok merci pour le tuyau, effectivement j'ai toujours du mal à voir ce pour quoi est fait prxchange (ce qui est quand même dans le nom de l'instruction ) et je ne l'utilise pas de façon optimale du coup.

Je reviendrais après des test comparatifs de rapidité
jerome_pdv2 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/05/2011, 14h20   #13
Membre confirmé
 
Inscription : janvier 2010
Messages : 185
Détails du profil
Informations forums :
Inscription : janvier 2010
Messages : 185
Points : 250
Points : 250
Tu dois bien voir un petit peu à quoi ça sert, non ? Parce que sinon tu ne serais pas arriver à ta solution... ou alors tu as beaucoup de chance.

On va repartir du début :

PRXPARSE sert à compiler une expression régulière (regexp) et renvoie un code qui sert à "étiqueter" cette expression compilée et à l'utiliser dans les autres fonction PRX.
A chaque iteration du PDV (a chaque ligne traitée), Le code vaut 1 pour la premiere regexp compilée, 2 pour la deuxième, etc.


On pourrait se passer de cette étape de pré-compilation et écrire directement les regexp dans les autres fonctions PRX comme ici:

Code :
1
2
3
4
5
6
7
8
9
10
11
12
DATA test;
length texte $32 ;
input texte  $32.;
position_de_toto=prxmatch("/toto/", texte); 
cards ;
123 Blagues toto répertoriées
ON se marre !
Non  ?
;
run;
proc print;
run;
Les inconvénients d'une telle écriture :
1. l'expression est compilée à chaque exécution de la(des) fonction(s) qui l'utilise(nt).
2. Il faut retaper l'expression chaque fois qu'on veut l'utiliser dans une fonction.

Dans notre exemple :
Code :
position_de_toto=prxmatch("/toto/", texte);
equivaut à l'écriture un peu meilleure (en terme d'habitude de codage) :
Code :
1
2
reg=prxparse("/toto/"); 
position_de_toto=prxmatch(reg, texte);
La deuxième écriture permet en effet de réutiliser l'expression dans autant de fonctions que l'on veut en utilisant la valeur de reg.
Ici il n'y a qu'une seule fonction donc finalement on y perd du point de vue du développeur feignant.

Mais il y a encore mieux : conditionner la compilation par _N_=1 et retenir la valeur reg. Cela évitera le travail de compilation de la même expression à chaque itération du PDV : SAS va conserver dans sa mémoire l'expression compilée dès la premiere itération sans jamais l'écraser par une recompilation.
On pourra utiliser cette regexp autant de fois que nécessaire en utilisant simplement l'étiquette conservée dans reg.

D'où l'écriture un peu fastidieuse du retain + if _n_=1 then prxparse dans les exemples donnés par SAS.
Ce sont des habitudes de programmation à prendre même sur des exemples simples car ils évitent des écueils sur les programmes plus compliqués.

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
DATA test;
length texte $32 ;
retain reg;
input texte  $32.;
IF _n_=1 then reg=prxparse("/toto/"); 
position_de_toto=prxmatch(reg, texte); 
cards ;
123 Blagues toto répertoriées
ON se marre !
Non  ?
;
run;
proc print;
run;
Maintenant pour revenir à ta question, la fonction PRXCHANGE comme son nom l'indique sert à faire de la substitution de chaine de caracteres.
Elle ne fonctionne qu'avec des regexp de subtitution c'est à dire de la forme s/chaine a substituer/substitu/.


Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 
DATA test;
length texte $32 ;
retain reg;
input texte  $32.;
IF _n_=1 then reg=prxparse("s/toto/titi/"); 
/* position_de_toto donne la position de la premiere chaine toto */
position_de_toto=prxmatch(reg, texte); 
/* on substitue les 2 premieres occurences de toto */
call prxchange(reg, 2, texte); 
cards ;
123 Blagues toto répertoriées
ON se marre !
Non  ?
toto et toto
toto et toto et toto
;
run;
proc print;
run;
Bon je m'arrête là car il y a énormément à dire sur les regexp et qu'un apres-midi n'y suffirait pas...
sasadm est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/05/2011, 17h09   #14
Membre éclairé
 
Homme
statisticien
Inscription : mai 2011
Messages : 212
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : statisticien
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : mai 2011
Messages : 212
Points : 319
Points : 319
oui, lorsque je disais j'ai du mal à voir, c'est qu'en fait je raisonnais toujours par une description totale de la chaine, alors que prxchange travaille aussi sur des portions de la chaine.

Je m'attaque à des choses plus compliquées maintenant les étages...

J'ai repris ton code comme départ

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
 
DATA traitement_etage;
SET etage2;
length num $5. ssetage $46. ;
 
IF _N_=1 then 
do;
call prxdebug(1);
retain tr_etage
;
tr_etage=prxparse("s/\s([0-9][0-9]?)\s?(ER|EME?|E)\s(ETAGE|ET|ETG)\s/ /");
call prxdebug(0);
end;
 
IF (INDEX(cpl_adresse_N," ETAGE ") 
OR INDEX(cpl_adresse_N," ET ") 
OR INDEX(cpl_adresse_N," ETG ")) THEN DO;
     pos=prxmatch(tr_etage, cpl_adresse_N);
	IF pos  then do;
		num=prxposn(tr_etage,1, cpl_adresse_N);
		call prxchange(tr_etage, 1,cpl_adresse_N,ssetage);
	             end;
				 else ssetage=cpl_adresse_N;
                                            END; 
								  ELSE ssetage=cpl_adresse_N;
 
run;
Je ne cherche pas à ce que ça en fasse plus pour l'instant, les cas où ETAGE est encore présent dans la chaîne nettoyée pouvant être des cas avec le numéro d'étage à droite plutôt qu'à gauche, et donc nécessitent un nettoyage des autres termes avant de pouvoir décider dans quel cas on se trouve et alors pouvoir nettoyer correctement...

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 
               Obs    cpl_adresse_N             num    ssetage
 
                    1    1ER ETAGE PORTE 2         1      PORTE 2
                    2    APT 1473 15EME ETAGE      15     APT 1473
                    3    3E ETAGE                  3
                    4    BAT T2 APT 11 1 ETAGE            BAT T2 APT 11 1 ETAGE
                    5    HLM 4E ETAGE APT 122      4      HLM APT 122
                    6    APPT 135 ETAGE 2                 APPT 135 ETAGE 2
                    7    4EME ETAGE GAUCHE         4      GAUCHE
                    8    ETAGE 3                          ETAGE 3
                    9    PORTE 6 ETAGE 2                  PORTE 6 ETAGE 2
                   10    PORTE 33  6 ETAGE                PORTE 33  6 ETAGE
                   11    7 EM ETAGE APP 29         7      APP 29
                   12    5 EME ETAGE               5
                   13    LOTISSEMENT 2 ETAGE              LOTISSEMENT 2 ETAGE
                   14    BAT 2 ETAGE 3                    BAT 2 ETAGE 3
                   15    BT H2 2E ETAGE            2      BT H2
                   16    8E ETAGE 2E PTE GAUCHE    8      2E PTE GAUCHE
                   17    6E ETAGE                  6
                   18    APPT NO 54   5E ETAGE     5      APPT NO 54
                   19    BAT COUR 4EME ETAGE       4      BAT COUR
                   20    3 EME ETAGE               3
jerome_pdv2 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/05/2011, 14h37   #15
Membre éclairé
 
Homme
statisticien
Inscription : mai 2011
Messages : 212
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : statisticien
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : mai 2011
Messages : 212
Points : 319
Points : 319
Quelques questions au spécialistes ou non... :

1- Les buffers font perdre du temps, mais les parenthèses "sans capture" c'est à dire les expressions du type (?:...) font elles en perdre autant où bien sont elles plus légères ?

2 - Y a t il moyen de définir des "sous motifs" à l'intérieur de nos motifs ?
Ou on passe éventuellement par des macros variables ?

par exemple en écriture "approximative"

motif_de_base=prxparse(/blabla de base/);
motif_elaboré=prxparse(/truc1 (appel de motif_de_base) truc2 (appel de motif_de_base) truc3/);

3 - Quelle est la longueur maximale de la chaine de caractères définissant une regexp ?


Je me pose ces questions là car je commence à avoir des choses compliquées à base de briques élémentaires.., et j'aimerais pouvoir en simplifier l'écriture ainsi que la lecture.

Code :
1
2
3
4
5
6
7
 
tr_bat=
prxparse("s/\s(?:IMMEUBLE|IMM?|RESIDENCE|RES|TOUR|HLM|BATIMENT)((?:\sDE\sLE?A?|\sLA|\sLE?S?|\sDU|\sDE?S?)?\s[A-Z]{2,}(?:(?:\sDE\sLE?A?|\sLA|\sLE?S?|\sDU|\sDE?S?)\s[A-Z]{2,})?)\s(?:[^A-Z][^A-Z]\s?|$)/ /");
 
 
tr_quartier=
prxparse("s/\s(?:LIEU DIT|HAMEAU|HAM|QUARTIER)((?:\sDE\sLE?A?|\sLA|\sLE?S?|\sDU|\sDE?S?)?\s[A-Z]{2,}(?:(?:\sDE\sLE?A?|\sLA|\sLE?S?|\sDU|\sDE?S?)\s[A-Z]{2,})?)\s/ /");
jerome_pdv2 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 07h19.


 
 
 
 
Partenaires

Hébergement Web