Preg_match et expression régulière

Fermé
pontarose Messages postés 150 Date d'inscription vendredi 10 août 2007 Statut Membre Dernière intervention 23 avril 2010 - 3 févr. 2010 à 18:55
heyquem Messages postés 759 Date d'inscription mercredi 17 juin 2009 Statut Membre Dernière intervention 29 décembre 2013 - 10 févr. 2010 à 00:39
Bonjour,
j'ai un petit souci, j'aimerai vérifier que ma séquence contient seulement a, g, t ou c.
Mon souci est que mon expression régulière n'est pas valide mais je ne comprend pas pourquoi!!!!!!!!

$entry_sequence="aatgcatgtgactatcatatgtgcattgatact";
//$entry_sequence="sequencenecontenantpasqueagtc";
$valid_seq="/^([a|g|t|c])([a|g|t|c]+)([a|g|t|c])$/i";

if( preg_match($valid_seq,$entry_sequence) )
{
print("<b>La sequence contient que les bases A,G,T ou C</b><br>");
}
else
{
print("<b>PBE</b><br>");
exit;
}
Merci par avance

4 réponses

heyquem Messages postés 759 Date d'inscription mercredi 17 juin 2009 Statut Membre Dernière intervention 29 décembre 2013 131
4 févr. 2010 à 09:34
Salut

premièrement

[agtc] signifie: une lettre pouvant être a ou g ou t ou c.
Il n’est donc pas nécessaire de rajouter des |

En fait un ensemble définit des OU entre des lettres, tandis que | sert à définir des OU entre des groupes de plusieurs lettres.



deuxièmement

à quoi sert de mettre ^([agtc])([agtc]+)([agtc])
plutôt que ^[agtc]+$ ?



troisièmement

plutôt que de vérifier que tous les caractères sont des agct, je préfère vérifier qu’aucune lettre n’est différente de agct, avec ^[^agtc]+$ –> aucun match trouvé.

Mais je n’ai pas d’argument pour appuyer cette préférence !
0
Bonjour,

merci beaucoup pour ta réponse et tes explications.


J'ai testé mon script ce matin avant de voir ta réponse, et il se trouve que cela fonctionne. Je ne sais pas pourquoi cela ne fonctionnait pas.
Merci pour tes explications j'ai bien compris l'utilisation de |.
0
heyquem Messages postés 759 Date d'inscription mercredi 17 juin 2009 Statut Membre Dernière intervention 29 décembre 2013 131
4 févr. 2010 à 17:08
Cela fonctionne en effet.

Mais [a|g|t|c] signifie: un quelconque des caractères ’a’,’|’,’g’,’t’,’c’.

C’est à dire que ’|’ n’est pas considéré comme le signe OU mais comme un caractère normal.

Les caractères spéciaux perdent en effet leur spécialité dans un ensemble.

Ainsi la regex définie à partir de [a|g|t|c]* va matcher ’atcgtctg’ mais aussi ’ct|agc|tca|t’, ce qui est à tout le moins inutile.



Salut
0
pontarose Messages postés 150 Date d'inscription vendredi 10 août 2007 Statut Membre Dernière intervention 23 avril 2010 2
5 févr. 2010 à 11:37
Bonjour,

Encore merci.

Dans mon cas vue que je ne veux que agtc (je ne veux pas |) jois dois mettre
$valid_seq="/^[agtc]+$/i";
Dans le cas ou cela commence par un atg obligatoirement et finis par taa ou tag ou tga et qu'entre cela je dois a ou g ou t ou c; je peux écrire:
$valid_seq="/^(atg)([agtc]+)([taa|tag|tga])$/i";
0
heyquem Messages postés 759 Date d'inscription mercredi 17 juin 2009 Statut Membre Dernière intervention 29 décembre 2013 131
10 févr. 2010 à 00:39
Non. Tu recommences la même erreur.
[taa|tag|tga] signifie: un quelconque des caractères ’t’ , ’a’ , ’|’ , ’g’

Il faut s’habituer à l’idée que ’|’ ne s’emploie dans un ensemble que s’il y représente simplement ’|’ et non pas l’opérateur OU.

Le mot “un“ est important dans la formulation, c’est mieux que dire: n’importe quel caractère parmi ’t’ , ’a’ , ’|’ , ’g’
Parce que ça insiste sur le fait que ce qui est entre crochets [ ] représente 1 seul caractère.
Et ce caractère n’est ni fixe , ni représentable par une des séquences spéciales ( \d , \t, \n, \w etc), ni un caractèes quelconque comme le spécifie un point .
Il faut donc mettre entre crochet un ensemble de symboles pour représenter les possibles caractères. Il s’agit d’une définition personnalisée d’UN caractère du texte exploré.

Pour symboliser que PLUSIEURS caractères successifs du texte exploré peuvent avoir exactement la même variabilité, il faut multiplier l’ensemble défini entre crochet par une symbolique multiplicatrice: * ou + ou {4} ou {2,7}




Deuxième chose qui me semble suspecte, ce sont les parenthèses.

Les parenthèses dans une RE définissent obligatoirement un groupe, c’est à dire une ou des positions dont le moteur de regex va relever les caractères dans une chaîne matchante qui matche avec la RE.
Dans le cas de ta RE, je ne vois pas à quoi va te servir d’attraper les caractères matchant avec le groupe (atg) puisque ce ne pourra pas être autre chose que atg.

==> cela me fait douter que des parenthèses soient vraiment nécessaires autour de [taa|tag|tga]
Quoique il peut être justifié d’en mettre si tu veux savoir quel sera exactement le groupe de 3 lettres à ces positions dans une chaîne matchante.
Mais bon, j’ai l’impression que tu mets des parenthèses parce que tu as la vague idée qu’elles limitent l’extension de [taa|tag|tga] que tu n’arrives pas à voir comme symbole d’UN caractère.



Le problème est de représenter un OU entre 3 triplets de caractères: il faut bien limiter l’extension de OU à droite et à gauche, mais si on le fait avec des parenthès , on définit un groupe.

La bonne RE que tu recherches est, à mon avis:
$valid_seq="/^atg([agtc]+)(?:taa|tag|tga)$/i";

L’écriture (?: ) définit un groupe non capturant. Il n’y aura aucun groupe numéroté correspondant à ces positions dans le MatchObject d’un match.


Autre possibilité:
$valid_seq="/^atg([agtc]+)t(?:aa|ag|ga)$/i";

Ou encore
$valid_seq="/^atg([agtc]+)t(?:a[ag]|ga)$/i";


Salut.
0