Rechercher : dans
Par :

[expressions régulières] question preg_match

Dernière réponse le 22 oct 2008 à 15:17:32 muaddibx, le 15 oct 2008 à 15:18:35 
 Signaler ce message aux modérateurs

Bonjour,

Je suis sur un ptit script qui va utiliser des expressions régulières, et j'aurais souhaité avoir une info que je n'ai pas trouvé.

En fait, je veux faire un preg_match sur plusieurs expressions régulières, du style:
preg_match(regexp1 OU regex2 OU regexp3, "un texte à analyser")

avec regexpX étant les différentes expressions que je veux tester.

Mon soucis est donc le suivant:
Est-il possible d'inclure les "conditions" OU dans mon preg_match, ou bien suis-je obligé de multiplier cette ligne autant de fois que j'ai de regexp (dans mon exemple, ca ferait donc 3 fois)?
Et si oui, quel est le symbole de OU? (je parle pas du OU qu'on met dans une classe de caractère hein, mais bien un OU qu'on placerait dans le preg_match.

En espérant bien m'etre fait comprendre, je vous souhaite une bonne journée.

Merci d'avance.

Muad'Dib

Configuration: Windows XP
Firefox 3.0.3

Meilleures réponses pour « [expressions régulières] question preg_match » dans :
PHP - Expressions régulières Voir Qu'est-ce qu'une expression régulière? Les expressions régulières sont des modèles créés à l'aide de caractères ASCII permettant de manipuler des chaînes de caractères, c'est-à-dire permettant de trouver les portions de la chaîne correspondant au...
Google - Recherche d'une expression exacte VoirLorsque l’on souhaite faire la recherche d’une expression exacte, il suffit de mettre cette expression entre guillemets. Exemple : "animal domestique" référencera uniquement les sites comportant l’expression "animal domestique".
Sed - Trucs et astuces VoirSubstitution Affichage Suppression Espace et tabulation Ligne vide Intervalle régulier Divers Joindre des lignes Affichage insensible à la casse Substitution Substituer "foo" par "bar" à chaque ligne Seulement la 1ère...
Javascript - L'objet RegExp VoirLes particularités de l'objet RegExp L'objet RegExp est un objet permettant de manipuler des expressions régulières, c'est-à-dire des modèles créés à l'aide de caractères ASCII permettant de manipuler des chaînes de caractères, afin de trouver des...

1

kilian, le 15 oct 2008 à 15:46:36
  • +1

Salut,

En utilisant le pipe:

(exp1)|(exp2)
Le gâteau est un mensonge!

Répondre à kilian

2

muaddibx, le 15 oct 2008 à 15:50:25

Ok, nikel

Merci bien kilian :)

Jvais aller tester ca de suite

Répondre à muaddibx

3

muaddibx, le 15 oct 2008 à 16:52:35

Hum, jcommence à me casser un peu les dents lol...
J'essaie d'intégrer cela dans un script, et la syntaxe semble foirer quelque part sur le preg_match :s

voici mon script:

function AnalyseEtTraite ()
{
$repname=$1
if [preg_match ("#^\\[a-zA-Z0-9_ ()-]+\\$|^\\[a-zA-Z0-9_ ()-]+\\(CHANTIER|CLIENT|CONTRAT|PREVENTION|PRIME|SINISTRE)\\$|^\\[a-zA-Z0-9_ ()-]+\\CHANTIER\\[a-zA-Z0-9_ ()-]+\\$|^\\[a-zA-Z0-9_ ()-]+\\CHANTIER\\[a-zA-Z0-9_ ()-]+\\DOSSIER\\$|^\\[a-zA-Z0-9_ ()-]+\\CONTRAT\\[a-zA-Z0-9_ ()-]+\\$|^\\[a-zA-Z0-9_ ()-]+\\CONTRAT\\[a-zA-Z0-9_ ()-]+\\DOSSIER\\$|^\\[a-zA-Z0-9_ ()-]+\\PREVENTION\\[a-zA-Z0-9_ ()-]+\\$|^\\[a-zA-Z0-9_ ()-]+\\PRIME\\CIES\\$|^\\[a-zA-Z0-9_ ()-]+\\SINISTRE\\[a-zA-Z0-9_ ()-]+\\$|^\\[a-zA-Z0-9_ ()-]+\\SINISTRE\\[a-zA-Z0-9_ ()-]+\\(ASSURANCE|DOSSIER|EXPERTISE)\\$#",$repname)] ; then
   echo $1
fi
};
find . -type d -exec AnalyseEtTraite {} \;


Si je simplifie le gros paté, ca équivault à ca:
function AnalyseEtTraite ()
{
$repname=$1
if [preg_match ("#regexp1|regexp2|regexp3#",$repname)] ; then
   echo $1
fi
};
find . -type d -exec AnalyseEtTraite {} \;


Et quand j'exécute le script, il me donne le message suivant:
 line 4: syntax error near unexpected token `"#^\\[a-zA-Z0-9_ ()-]+\\$|^\\[a-zA-Z0-9_ ()-]+\\(CHANTIER|CLIENT|CONTRAT|PREVENTION|PRIME|SINISTRE)\\$|^\\[a-zA-Z0-9_ ()-]+\\CHANTIER\\[a-zA-Z0-9_ ()-]+\\$|^\\[a-zA-Z0-9_ ()-]+\\CHANTIER\\[a-zA-Z0-9_ ()-]+\\DOSSIER\\$|^\\[a-zA-Z0-9_ ()-]+\\CONTRAT\\[a-zA-Z0-9_ ()-]+\\$|^\\[a-zA-Z0-9_ ()-]+\\CONTRAT\\[a-zA-Z0-9_ ()-]+\\DOSSIER\\$|^\\[a-zA-Z0-9_ ()-]+\\PREVENTION\\[a-zA-Z0-9_ ()-]+\\$|^\\[a-zA-Z0-9_ ()-]+\\PRIME\\CIES\\$|^\\[a-zA-Z0-9_ ()-]+\\SINISTRE\\[a-zA-Z0-9_ ()-]+\\$|^\\[a-zA-Z0-9_ ()-]+\\SINISTRE\\[a-zA-Z0-9_ ()-]+\\(ASSURANCE|DOSSIER|EXPERTISE)\\$#",$repname'


Pour finir, je tenais juste à préciser que j'écris ce script dans un terminal, sur Debian.

Voilà, donc je reste preneur de toute info utile (ou pas :p ).

Répondre à muaddibx

4

kilian, le 15 oct 2008 à 16:59:57

Tu as oublié de mettre tes expressions entre parenthèses.

abcd|efgh ça signifie abc(d ou e)fgh
Alors que (abcd)|(efgh) ça signifie ce que tu voulais ;-)

Après l'erreur de syntaxe par contre je ne saurais pas trop te dire.... Ya beaucoup de choses.... Le gâteau est un mensonge!

Répondre à kilian

5

muaddibx, le 15 oct 2008 à 17:12:59

Oki, j'ai donc modifié cela... mais c'est sure que les regexp prennent pas mal de place ><

Sinon, après modif, voici le nouveau message d'erreur:

./DroitsCour: line 4: syntax error near unexpected token `newline'
./DroitsCour: line 4: `if [preg_match ('

avec DroitCour étant le nom du script

NB: le message d'erreur s'arrete bien au dernier " ' "... le terminal n'a pas mis tout le paté de regexp

C'est là où je me demande si preg_match est bien "installé" sur ma debian

Répondre à muaddibx

6

muaddibx, le 15 oct 2008 à 17:24:05

Juste au cas où ca paraisse plus clair, j'ai refait la mise en forme du script:

function AnalyseEtTraite ()
{
$repname=$1
if [preg_match (
"#
(^\\[a-zA-Z0-9_ ()-]+\\$)|
(^\\[a-zA-Z0-9_ ()-]+\\(CHANTIER|CLIENT|CONTRAT|PREVENTION|PRIME|SINISTRE)\\$)|
(^\\[a-zA-Z0-9_ ()-]+\\CHANTIER\\[a-zA-Z0-9_ ()-]+\\$)|
(^\\[a-zA-Z0-9_ ()-]+\\CHANTIER\\[a-zA-Z0-9_ ()-]+\\DOSSIER\\$)|
(^\\[a-zA-Z0-9_ ()-]+\\CONTRAT\\[a-zA-Z0-9_ ()-]+\\$)|
(^\\[a-zA-Z0-9_ ()-]+\\CONTRAT\\[a-zA-Z0-9_ ()-]+\\DOSSIER\\$)|
(^\\[a-zA-Z0-9_ ()-]+\\PREVENTION\\[a-zA-Z0-9_ ()-]+\\$)|
(^\\[a-zA-Z0-9_ ()-]+\\PRIME\\CIES\\$)|
(^\\[a-zA-Z0-9_ ()-]+\\SINISTRE\\[a-zA-Z0-9_ ()-]+\\$)|
(^\\[a-zA-Z0-9_ ()-]+\\SINISTRE\\[a-zA-Z0-9_ ()-]+\\(ASSURANCE|DOSSIER|EXPERTISE)\\$)
#",$repname)] ; then
   echo $1
fi
};
find . -type d -exec AnalyseEtTraite {} \;

Répondre à muaddibx

8

kilian, le 15 oct 2008 à 17:41:34

IL faut que ton expression soit une seule ligne.... Le gâteau est un mensonge!

Répondre à kilian

7

kilian, le 15 oct 2008 à 17:27:58

Mais j'y pense, tu peux pas faire:

if [commande (prout, bidule)]

Pour tester une commande il faut que tu fasses:
if [ -n "$( commande prout bidule )"  ]

Le -n teste si la chaîne n'est pas vide.
Le gâteau est un mensonge!

Répondre à kilian

9

muaddibx, le 16 oct 2008 à 10:39:10

Mouarf, je crois avoir décelé une nouvelle erreur :s

Oui, sinon, j'ai résolu mon soucis précédent; j'avais oublié de définir le type de script en en tete, et j'avais zappé le $ devant la fonction, dans mon find.

Seulement je me suis apercu qu'avec ma commande, ca traite tous les répertoires sans exception... (je veux faire un chmod sur les répertoires ciblés).

J'ai essayé de changer mes antislash en slash, mais ca donne toujorus la meme chose. Par contre, j'ai pas mis un antislash derriere. Voici un exmeple de regexp:

#^/[a-zA-Z0-9_ ()-]+/CHANTIER/[a-zA-Z0-9_ ()-]+/$#


Je précise que mes slash sont là pour marquer les séparations entre chaque répertoire.

En espérant que ca vous parle^^

Répondre à muaddibx

10

muaddibx, le 16 oct 2008 à 14:17:34

Je viens de capter un truc avec les regexp... un truc qui va pas me convenir du tout lol...

Quand je fais une regexp comme celle là:
#^/[a-zA-Z0-9_ ()-]+/CHANTIER/[a-zA-Z0-9_ ()-]+/$#

Ca va me donner TRUE pour le répertoire /toto/CHANTIER/tutu/

Mais ca va aussi me donner TRUE pour /toto/CHANTIER/tutu/etzut ... cest bien ca non?

Helas, je souhaite juste que la regexp me donne TRUE pour /toto/CHANTIER/tutu/ et que ca aille pas "valider" tous les sous répertoires de la meme arborescence :s

Y aurait-il un moyen de le spécifier quelquepart?

Répondre à muaddibx

11

kilian, le 16 oct 2008 à 14:25:13

Essaie comme ça:

#^/[a-zA-Z0-9_ ()-]+?/CHANTIER/[a-zA-Z0-9_ ()-]+?/$#
Le gâteau est un mensonge!

Répondre à kilian

12

muaddibx, le 16 oct 2008 à 14:57:16

Raaa, ca commence a devenir pesant cette histoire de regexp lol...

Bon, histoire d'etre sure que je soie sur les bons rails:

- j'ai mis ca en debut de script:

#!/bin/sh

Je sais pas trop ce que ca veut dire... mais j'ia cruc omprendre que je devais initialiser un langage, pour que le shell comprenne mon script.
Mais bon, je suis vraiment pas certain qu'un terminal debian comprenne un preg_match ...
Si vous pouviez me confirmer ce point, ca serait bien cool.

Sinon, pour ta dernière remarque, kilian, je suis pas sure que ca marche ton truc avec "+?" (ca voudrait dire répéter au moins une fois, et/ou répéter 0,1 ou plusieurs fois, d'où une redondance... à voir). J'ai testé, ca n'a rien changé (a mon avis, c'est car le preg_match ne doit pas du tout marcher, donc normal que ca change rien).

Enfin bref, j'avoue que je me sens un poil dépassé là...

(en tout cas, vraiment merci ton aide kilian; sans toi, j'aurais surement pas mal de cheveux en moins :p)

Répondre à muaddibx

13

kilian, le 16 oct 2008 à 16:19:54

#!/bin/sh

Je sais pas trop ce que ca veut dire... mais j'ia cruc omprendre que je devais initialiser un langage, pour que le shell comprenne mon script.


Oui, c'est un Sha-Bang :-)

Bonche, je suis au boulot et j'ai un Linux dans une machine virtuelle, je vais tester quelques expressions régulières pour résoudre ton soucis. Le gâteau est un mensonge!

Répondre à kilian

14

muaddibx, le 16 oct 2008 à 17:07:36

Sympa le nom lol

Chui allé voir, histoire d'en apprendre un peu plus à ce sujet, et jpense qu'un #!/usr/bin/perl
serait plus approprié... quoi que :p

Enfin bref, je continue de voir ca de mon coté; merci encore pour tout.

++

Répondre à muaddibx

15

kilian, le 16 oct 2008 à 17:40:30

Finalement j'ai pas le temps de tester un script :-s
Je pourrais pas regarder avant la semaine prochaine en plus, désolé :-s Le gâteau est un mensonge!

Répondre à kilian

16

muaddibx, le 17 oct 2008 à 09:25:30

EDIT: bon, j'ai rien dit. Je retravaille dans mon ptit coin, et jvous redonne des nouvelles fraiches dès que possible.
A pluche!


Juste une petite question, et jpense deja que ca devrait bien m'aider:
comment faire pour rechercher une chaine exacte, et pas ces dérivés?
Je m'explique par un exemple:
j'ai l'arborescence suivante:
/CHANTIER/NomChantier/DOSSIER
/DIVERS
/DIVERS

Je souhaite donc ne sélectionner que les répertoires CHANTIER, NomChantier et DOSSIER, pour leur attribuer des droits spécifiques.
J'ai tenté avec des expressions régulières, mais jviens de m'apercevior qu'avec mes regexp, ca renvoie toute les sous-couches avec. Donc je vois pas trop comment faire... en gros, jvoudrais qu'un preg_match (#guitare#, "j'aime la guitare") me renvoi un false; sinon, tous les sous-répertoires seront TRUE :s

Si chui pas bien clair, hésitez pas à me le dire, j'essairais de clarifier la chose.

Merci d'avance.

Muad'Dib

Répondre à muaddibx

17

kilian, le 17 oct 2008 à 14:57:19

Salut,

Tu fais comme ça:

^machaineconstante$
Le gâteau est un mensonge!

Répondre à kilian

18

muaddibx, le 17 oct 2008 à 17:20:39

Ouep, c'est ca^^

J'ai pas mal avancé sur mon script là. Donc maintenant, ca marche "correctement". Il me manque juste à mettre en place la récursivité, pour qu'il aille voir dans les sous-répertoires.

Voici mon code pour le moment:

#!/usr/bin/perl
my $string2 = '^[a-zA-Z0-9_ ()-]+$';
my ($fichier, $dossier) = (undef, '/home/thib/RepAAnalyser');
opendir (my $dir, $dossier) or die "$dossier n'existe pas !";
my @files = readdir $dir;
foreach $fichier (@files)
{
  if ((-d "$dossier/$fichier") && ($fichier =~ m/$string2/))
     {  print "$fichier\n";
        AnalyseDir ("$dossier/$fichier");
     };

}
closedir $dir;


Ce code me renvoi bien les répertoires contenus dans RepAAnalyser, mais pas les sous répertoires.

J'espère que la suite sera pas trop laborieuse :p

Répondre à muaddibx

19

muaddibx, le 20 oct 2008 à 15:28:37

Hum,

Personne aurait une ptite idée pour avoir une récursivité de ce programme?

Répondre à muaddibx

20

muaddibx, le 22 oct 2008 à 11:22:31

Rebonjour,

J'ai un peu avancé sur mon script, mais je patauge encore :s

En fait, je viens de m'apercevoir que la fonction grep analyse des chaines de caractères, ou bien des contenus de fichier. Par contre, ca a pas l'air de marcher sur le renvoi d'un find, meme si c'est une chaine de caractère... j'aurais bien aimé avoir confirmation de cela.
J'ai fait un ou deux test de mon coté, et quand j'envoi le resultat de mon find dans un fichier, ca va nikel, mais quand je lance le grep directement à la suite du find, ca ne marche pas.
Vu le nombre de répertoires à analyser (environ 100 000), je me vois pas trop les mettre tous dans un fichier que j'analyserais par la suite.

Auriez vous une ou deux pistes à me donner? en gros, je cherche maintenant une fonction qui marche comme grep, mais qui peut travailler sur des répertoires.

Je vous laisse ici mes scripts:
- script find:

#!/bin/sh
find . -type d -exec /home/thib/BupCOURvoip/creadoc080920/analyse {} \;

- script de la fonction analyse:
#!/bin/sh
grep ^\./infrasud $1
if [ "$?" -eq "0" ]; then
echo $1
fi

Répondre à muaddibx

21

kilian, le 22 oct 2008 à 11:28:55

Normalement find est fait pour ça.
Tu veux retenir quoi comme style de chemin de fichier? Le gâteau est un mensonge!

Répondre à kilian

22

muaddibx, le 22 oct 2008 à 11:35:14

En fait, je souhaite sélectionner un ensemble de répertoires (grace aux regexp^^), et leur attribuer certains droits (setgid en particulier).

Donc avec le find, jtrouve tous les répertoires. Mais j'arrive pas à n'en prendre qu'une partie pour les traiter par la suite.
Enfin, j'y arrive si je mets tous les répertoires dans un fichier; avec grep, ca marche. Mais je ne souhaite pas mettre cette liste dans un fichier, car j'ai bien trop de répertoires.

EDIT: et donc comme style de chemin de fichier, cest un peu compliqué à expliquer car yen a pas mal de styles. Cest pour cela que je souhaitait utiliser les expressions régulières

Répondre à muaddibx

23

kilian, le 22 oct 2008 à 11:50:46

A d'accord et donc avec grep tu voudrais ne récupérer que la partie qui t'interesse dans un chemin? Le gâteau est un mensonge!

Répondre à kilian

24

muaddibx, le 22 oct 2008 à 11:53:25

Je souhaite récupérer tout le chemin du répertoire, pour lui attribuer de nouveaux droits.

j'ai essayé un "find -name", mais ca n'a l'air de s'occuper que des fichiers, et non des répertoires :s

EDIT: oui, je tenais à préciser que dans mon script, j'ai pas mis toutes les regexp. Pour l'instant, je teste juste avec une simple expression (ici, infrasud, voire ^infrasud). Et quand ca marchera, j'essaierais de mettre toutes mes regexp, ou bien de multiplier ma ligne de find.

Répondre à muaddibx