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 14/12/2011, 21h06   #1
Candidat au titre de Membre du Club
 
Femme
Conseil - Consultant en systèmes d'information
Inscription : novembre 2011
Messages : 80
Détails du profil
Informations personnelles :
Sexe : Femme
Localisation : Maroc

Informations professionnelles :
Activité : Conseil - Consultant en systèmes d'information
Secteur : Conseil

Informations forums :
Inscription : novembre 2011
Messages : 80
Points : 12
Points : 12
Par défaut Extraire les expressions entre parenthèse

Bonjour,

Dans une table, j'ai des enregistrement qui ont valeur comme par exemple :

"(5+3)*2*((1>=0;-4;5)>=0;7;5*(3+4))", j'ai besoin d'une fonction qui me permet d'extraire les expressions entre parenthèses, dans ce cas par exemple: je veux récupérer (5+3) et (1>=0;-4;5) et (3+4) et ((1>=0;-4;5)>=0;7;5*(3+4))

J'ai essayé avec scan, mais il ne permet po d'extraire une expression entre deux caractères. Merci bien pour votre aide.
aminao est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/12/2011, 22h45   #2
Membre éclairé
 
Homme
statisticien
Inscription : mai 2011
Messages : 213
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 : 213
Points : 319
Points : 319
Bonsoir,

le mieux je pense c'est d'utiliser les expressions régulières et ça va nécessiter un minimum de programmation.

Il va falloir explorer ta variable avec l'expression régulière suivante :

parenthese_elementaire=prxparse('s/(.*)(\()([^\(\)]*)(\))(.*)/$1[$3]$5/');

Cette expression régulière va chercher quelque chose commençant par une parenthèse ouvrante suivi de quelque chose ne contenant ni une parenthèse ouvrante ni une parenthèse fermante et suivi d'une parenthèse fermante.

Elle va remplacer la parenthèse fermante par un crochet fermant et la parenthèse ouvrante par un crochet ouvrant et extraire ce qui était dans la parenthèse dans motif3.
Ensuite on re transforme dans motif3 les crochets par des parenthèses et on rajoute les parenthèses à chaque extrémité.

Et on répète de nouveau etc...

Il faut faire un test ad hoc et répéter le processus tant que l'on trouve la parenthèse.

Le code d'extraction a mettre dans la boucle est le suivant

Code :
1
2
3
4
5
6
7
8
9
 
IF INDEX(modif,'(')
then do;
calcul=modif;
t=prxmatch(parenthese_elementaire,calcul);
motif3=translate('('!!strip(prxposn(parenthese_elementaire,3,calcul))!!')','()','[]');
modif=prxchange(parenthese_elementaire,1,calcul);
output;
end;
Je n'ai pas réussi à programmer la boucle (c'est pas mon fort je te laisse le faire ou à d'autres...). J'avais fait un test "do until test; ....... ; end;" mais j'ai pas réussi à avoir un test valable

J'ai donc répété 4 fois l'opération dans le code suivant

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
 
DATA a;
calcul="(5+3)*2*((1>=0;-4;5)>=0;7;5*(3+4))";output;
calcul="(5+3)";output;
calcul="2*(5+3)*3";output;
calcul="2*(5+3)";output;
calcul="(5+3)*3";output;
run;
 
 
 
DATA b;
SET a;
length modif $50. motif3 $50.;
retain parenthese_elementaire ;
DROP modif parenthese_elementaire t;
IF _n_=1 then do;
parenthese_elementaire=prxparse('s/(.*)(\()([^\(\)]*)(\))(.*)/$1[$3]$5/');
end;
 
t=prxmatch(parenthese_elementaire,calcul);
motif3=translate('('!!strip(prxposn(parenthese_elementaire,3,calcul))!!')','()','[]');
modif=prxchange(parenthese_elementaire,1,calcul);
output;
 
 
IF INDEX(modif,'(')
then do;
calcul=modif;
t=prxmatch(parenthese_elementaire,calcul);
motif3=translate('('!!strip(prxposn(parenthese_elementaire,3,calcul))!!')','()','[]');
modif=prxchange(parenthese_elementaire,1,calcul);
output;
end;
 
 
IF INDEX(modif,'(')
then do;
calcul=modif;
t=prxmatch(parenthese_elementaire,calcul);
motif3=translate('('!!strip(prxposn(parenthese_elementaire,3,calcul))!!')','()','[]');
modif=prxchange(parenthese_elementaire,1,calcul);
output;
end;
 
 
 
IF INDEX(modif,'(')
then do;
calcul=modif;
t=prxmatch(parenthese_elementaire,calcul);
motif3=translate('('!!strip(prxposn(parenthese_elementaire,3,calcul))!!')','()','[]');
modif=prxchange(parenthese_elementaire,1,calcul);
output;
end;
 
 
IF INDEX(modif,'(')
then do;
calcul=modif;
t=prxmatch(parenthese_elementaire,calcul);
motif3=translate('('!!strip(prxposn(parenthese_elementaire,3,calcul))!!')','()','[]');
modif=prxchange(parenthese_elementaire,1,calcul);
output;
end;
 
run;
qui abouti à la sortie suivante qui est je crois plus ou moins ce que tu cherche

Code :
1
2
3
4
5
6
7
8
9
10
11
 
              Obs    calcul                                motif3
 
                1     (5+3)*2*((1>=0;-4;5)>=0;7;5*(3+4))    (3+4)
                2     (5+3)*2*((1>=0;-4;5)>=0;7;5*[3+4])    (1>=0;-4;5)
                3     (5+3)*2*([1>=0;-4;5]>=0;7;5*[3+4])    ((1>=0;-4;5)>=0;7;5*(3+4))
                4     (5+3)*2*[[1>=0;-4;5]>=0;7;5*[3+4]]    (5+3)
                5     (5+3)                                 (5+3)
                6     2*(5+3)*3                             (5+3)
                7     2*(5+3)                               (5+3)
                8     (5+3)*3                               (5+3)
jerome_pdv2 est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 14/12/2011, 23h20   #3
Membre éclairé
 
Homme
statisticien
Inscription : mai 2011
Messages : 213
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 : 213
Points : 319
Points : 319
bon voici avec une boucle du moment que tu n'a pas plus de 100 000 parenthèses ouvertes !

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
 
DATA a;
length calcul $100.;
calcul="(5+3)*2*((1>=0;-4;5)>=0;7;5*(3+4))";output;
calcul="(5+3)";output;
calcul="2*(5+3)*3";output;
calcul="2*(5+3)";output;
calcul="(5+3)*3";output;
calcul="(2*(18*(8-3)-(6-7)*2(1-(6*7)))-((2+(2*6))*3-2*((2*6)+(14-2*16))))";output;
run;
 
 
 
DATA b;
SET a;
length modif $100. motif3 $100.;
retain parenthese_elementaire ;
DROP modif parenthese_elementaire t;
IF _n_=1 then do;
parenthese_elementaire=prxparse('s/(.*)(\()([^\(\)]*)(\))(.*)/$1[$3]$5/');
end;
 
t=prxmatch(parenthese_elementaire,calcul);
motif3=translate('('!!strip(prxposn(parenthese_elementaire,3,calcul))!!')','()','[]');
modif=prxchange(parenthese_elementaire,1,calcul);
output;
 
do i= 1 TO 100000;
 
test=INDEX(modif,'(');
IF test 
then do;
calcul=modif;
t=prxmatch(parenthese_elementaire,calcul);
motif3=translate('('!!strip(prxposn(parenthese_elementaire,3,calcul))!!')','()','[]');
modif=prxchange(parenthese_elementaire,1,calcul);
output;
end;
else i=100001;
end;
run;
 
 
 
proc print DATA=b;run;
mais bon j'aurais été plus satisfait avec une boucle "do until" ...
jerome_pdv2 est déconnecté   Envoyer un message privé Réponse avec citation 30
Vieux 14/12/2011, 23h34   #4
Candidat au titre de Membre du Club
 
Femme
Conseil - Consultant en systèmes d'information
Inscription : novembre 2011
Messages : 80
Détails du profil
Informations personnelles :
Sexe : Femme
Localisation : Maroc

Informations professionnelles :
Activité : Conseil - Consultant en systèmes d'information
Secteur : Conseil

Informations forums :
Inscription : novembre 2011
Messages : 80
Points : 12
Points : 12
Pour utiliser les expressions régulières, dois-je forcement passer par étape Data?
ou bien peux-je les inclure dans une macro function?
aminao est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/12/2011, 00h15   #5
Membre éclairé
 
Homme
statisticien
Inscription : mai 2011
Messages : 213
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 : 213
Points : 319
Points : 319
En tant que code généré bien sûr

en tant que code générateur de code je n'ai jamais utilisé, je vais peut-être donc laissé à d'autre le soin de te répondre.

Cependant ce papier parle de l'utilisation des expressions régulières dans le code macro

http://www.lexjansen.com/pharmasug/2010/tt/tt10.pdf
jerome_pdv2 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 15/12/2011, 11h21   #6
Candidat au titre de Membre du Club
 
Femme
Conseil - Consultant en systèmes d'information
Inscription : novembre 2011
Messages : 80
Détails du profil
Informations personnelles :
Sexe : Femme
Localisation : Maroc

Informations professionnelles :
Activité : Conseil - Consultant en systèmes d'information
Secteur : Conseil

Informations forums :
Inscription : novembre 2011
Messages : 80
Points : 12
Points : 12
Merci infiniment Jerom pour vos réponses, je vais creuser plus
aminao est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/12/2011, 10h59   #7
Candidat au titre de Membre du Club
 
Femme
Conseil - Consultant en systèmes d'information
Inscription : novembre 2011
Messages : 80
Détails du profil
Informations personnelles :
Sexe : Femme
Localisation : Maroc

Informations professionnelles :
Activité : Conseil - Consultant en systèmes d'information
Secteur : Conseil

Informations forums :
Inscription : novembre 2011
Messages : 80
Points : 12
Points : 12
Bonjour les amis,

J'ai besoin cette fois d'extraire le dénominateur pour vérifier s'il est nul ou non, par exemple dans cet exemple "(5+3)/4*(3/(4-(2*2))" je veux récupérer les dénominateurs : 4 et (4-(2*2)). J'ai fé ca mais ca marche pas. Merci bien d'avance pour vos réponses.

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
DATA b;
SET a;
length modif $100. motif3 $100.;
retain parenthese_elementaire ;
DROP modif parenthese_elementaire t;
IF _n_=1 then do;
parenthese_elementaire=prxparse('s/(.*)\/(.*)/$1[$3]$5/');
end;
 
t=prxmatch(parenthese_elementaire,calcul);
motif3=translate('('!!strip(prxposn(parenthese_elementaire,3,calcul))!!')','/','|');
modif=prxchange(parenthese_elementaire,1,calcul);
output;
aminao est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/12/2011, 13h09   #8
Membre éclairé
 
Homme
statisticien
Inscription : mai 2011
Messages : 213
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 : 213
Points : 319
Points : 319
que se passe-t-il si tu as

'45/(2-5/(2*6-9*8))' ?

Tu as toujours seulement un niveau de / dans tes chaines ?
jerome_pdv2 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/12/2011, 14h31   #9
Modérateur
 
Homme Samir SELMANE
Consultant en Business Intelligence
Inscription : février 2011
Messages : 1 012
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 012
Points : 1 717
Points : 1 717
Citation:
Envoyé par jerome_pdv2 Voir le message
bon voici avec une boucle du moment que tu n'a pas plus de 100 000 parenthèses ouvertes !

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
 
DATA a;
length calcul $100.;
calcul="(5+3)*2*((1>=0;-4;5)>=0;7;5*(3+4))";output;
calcul="(5+3)";output;
calcul="2*(5+3)*3";output;
calcul="2*(5+3)";output;
calcul="(5+3)*3";output;
calcul="(2*(18*(8-3)-(6-7)*2(1-(6*7)))-((2+(2*6))*3-2*((2*6)+(14-2*16))))";output;
run;
 
 
 
DATA b;
SET a;
length modif $100. motif3 $100.;
retain parenthese_elementaire ;
DROP modif parenthese_elementaire t;
IF _n_=1 then do;
parenthese_elementaire=prxparse('s/(.*)(\()([^\(\)]*)(\))(.*)/$1[$3]$5/');
end;
 
t=prxmatch(parenthese_elementaire,calcul);
motif3=translate('('!!strip(prxposn(parenthese_elementaire,3,calcul))!!')','()','[]');
modif=prxchange(parenthese_elementaire,1,calcul);
output;
 
do i= 1 TO 100000;
 
test=INDEX(modif,'(');
IF test 
then do;
calcul=modif;
t=prxmatch(parenthese_elementaire,calcul);
motif3=translate('('!!strip(prxposn(parenthese_elementaire,3,calcul))!!')','()','[]');
modif=prxchange(parenthese_elementaire,1,calcul);
output;
end;
else i=100001;
end;
run;
 
 
 
proc print DATA=b;run;
mais bon j'aurais été plus satisfait avec une boucle "do until" ...
ou un do while ;
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
 
DATA c;
SET a;
length modif $100. motif3 $100.;
retain parenthese_elementaire ;
DROP modif parenthese_elementaire t;
IF _n_=1 then do;
parenthese_elementaire=prxparse('s/(.*)(\()([^\(\)]*)(\))(.*)/$1[$3]$5/');
end;
 
t=prxmatch(parenthese_elementaire,calcul);
motif3=translate('('!!strip(prxposn(parenthese_elementaire,3,calcul))!!')','()','[]');
modif=prxchange(parenthese_elementaire,1,calcul);
output;
 
 do while (INDEX(modif,'(')>0); 
      test=INDEX(modif,'(');
      calcul=modif;
      t=prxmatch(parenthese_elementaire,calcul);
      motif3=translate('('!!strip(prxposn(parenthese_elementaire,3,calcul))!!')','()','[]');
      modif=prxchange(parenthese_elementaire,1,calcul);
      output;
 end;
 
run;
s_a_m est déconnecté   Envoyer un message privé Réponse avec citation 10
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 05h01.


 
 
 
 
Partenaires

Hébergement Web