Problème avec une expression régulière

Eléphanteau du PHP | 30 Messages

28 août 2010, 00:28

Bonsoir tout le monde,

Alors voilà je cherche, je teste, mais je "reste plantée là"...
j'ai un formulaire qui teste si le numéro de téléphone commence par certains indicatifs et s'il a un certain nombre de chiffre, mes tests sont effectués dans un fichier checkEntries.php que j'appelle dans mon fichier formulaire.

voilà le code que j'ai pour l'instant pour le test du téléphone :
	
		case "gsmtest" :
		{
			$pattern = "((621|691|661|)+[0-9]{6,10})";
			break;
		}
Ce code marche très bien, mais j'aimerai rajouter aussi l'option de pouvoir autoriser les espaces et les signes de ponctuation.

J'avais tenté ça :
	case "gsmtest" :
		{
			$pattern = "[[:blank:][:punct:]](621|691|661|)+[0-9]{6,10})";
			break;
		}
		
mais ça ne marche pas :cry:
merci pour votre aide :priere:

Mammouth du PHP | 1967 Messages

28 août 2010, 01:00

Où veux tu permettre les espaces ?

Je pense que avec ton code tu les autorise au début et c'es tout
case "gsmtest" :
                {
                        $pattern = "(621|691|661|)+[0-9[:blank:][:punst:]]*)";
                        break;
                }
a plus de chance de fonctionner
mais un espace ou de la ponctuation avant le préfixe n'est pas autoriser, pour cela :
case "gsmtest" :
                {
                        $pattern = "[[:blank:][:punst:]]*(621|691|661|)+[0-9[:blank:][:punst:]]*)";
                        break;
                }
Mais alors tu ne vérifie plus ne nombre de chiffres
Spols
pour les fan de rubik's cube ou pour les curieux ==> le portail francophone du rubik's cube

ViPHP
ViPHP | 5462 Messages

28 août 2010, 01:06

il est pas bon ton regexp a la base déjà
si fais ca : 621000 c'est valide
si je fais ca aussi : 621621621621621621621621621621621621621621621621621621621621621621621621000

Eléphanteau du PHP | 30 Messages

28 août 2010, 01:15

Où veux tu permettre les espaces ?

Je pense que avec ton code tu les autorise au début et c'es tout
case "gsmtest" :
                {
                        $pattern = "(621|691|661|)+[0-9[:blank:][:punst:]]*)";
                        break;
                }
a plus de chance de fonctionner
mais un espace ou de la ponctuation avant le préfixe n'est pas autoriser, pour cela :
case "gsmtest" :
                {
                        $pattern = "[[:blank:][:punst:]]*(621|691|661|)+[0-9[:blank:][:punst:]]*)";
                        break;
                }
Mais alors tu ne vérifie plus ne nombre de chiffres
C'est compliqué... en fait je veux simplement que si la personne met un espace ou un signe de ponctuation, cela valide quand même le formulaire....

Eléphanteau du PHP | 30 Messages

28 août 2010, 01:16

il est pas bon ton regexp a la base déjà
si fais ca : 621000 c'est valide
si je fais ca aussi : 621621621621621621621621621621621621621621621621621621621621621621621621000
#-o tu as raison :(
mais pourquoi ?

ViPHP
ViPHP | 5462 Messages

28 août 2010, 01:21

il est pas bon ton regexp a la base déjà
si fais ca : 621000 c'est valide
si je fais ca aussi : 621621621621621621621621621621621621621621621621621621621621621621621621000
#-o tu as raison :(
mais pourquoi ?

((621|691|661|)+[0-9]{6,10})
veux dire
chaine qui commence par un ou plusieurs (621 ou 691 ou 661) suivis de 6 a 10 fois un chiffre entre 0 et 9

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

28 août 2010, 11:36

il faut essayer de comprendre comment se construit ton numéro de téléphone avant de se lancer dans les expressions régulières.
Une fois que tu as détaillés ça dans un français simple, l'expression régulière devient plus simple.

Commence donc par cette étape (obtenir une phrase du genre "un indicatif entre des valeurs connue, suivi de 4 fois une paire de chiffre. Une paire de chiffre peut commencer par une espace ou un point, suivi de 2 chiffres")
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Eléphanteau du PHP | 30 Messages

29 août 2010, 16:14

il faut essayer de comprendre comment se construit ton numéro de téléphone avant de se lancer dans les expressions régulières.
Une fois que tu as détaillés ça dans un français simple, l'expression régulière devient plus simple.

Commence donc par cette étape (obtenir une phrase du genre "un indicatif entre des valeurs connue, suivi de 4 fois une paire de chiffre. Une paire de chiffre peut commencer par une espace ou un point, suivi de 2 chiffres")
Mon numéro de tél doit commencer soit par 621 soit par 691 soit par 661 puis il est suivit de 6 chiffres (mais là c'est compliqué certaines personnes font de paires de 2 et d'autres de 3).
$pattern = "(^(621|691|661|)+[0-9]{6})";
mais le pb reste le même malgré le signe ^, si l'individu met que des 621 ça marche aussi...

pour les paires :
$pattern = "(^(621|691|661|)+([:blank:][:punct:][0-9]{2})+([:blank:][:punct:][0-9]{2})+([:blank:][:punct:][0-9]{2}))";
#-o

Mammouth du PHP | 1967 Messages

29 août 2010, 18:02

$pattern = "(^(621|691|661|)+([:blank:][:punct:][0-9]{2})+([:blank:][:punct:][0-9]{2})+([:blank:][:punct:][0-9]{2}))";
#-o
En premier lieu, l'indicatif doit être présent une et une seule fois ==> on le précise plutot que + (1 fois ou plus) ->{1} (une et une seule fois)
Ensuite le nombre de paire de 2, de 3 ou tout d'un coups est fixe pour un pays donné non ?
(Je suis belge donc je connais pas exactement le format visé)
j'ai cru comprendre 6 chiffres par paire de 2, 3 ou en un coups séparé par un espace ou de la ponctuation
En gros,
ok
621123456
621 123456
621 123 456
621 12 34 56
621.12.34.56
...
je proposerais
$pattern = '/^(621|691|661){1}(([[:punct:][:blank:]]{0,1}[0-9]{2}){3}|([[:punct:][:blank:]]{0,1}[0-9]{3}){2})$/';
code de test :
<?php
$pattern = '/^(621|691|661){1}(([[:punct:][:blank:]]{0,1}[0-9]{2}){3}|([[:punct:][:blank:]]{0,1}[0-9]{3}){2})$/';
echo $pattern.' <br>';
$test = array('621123456','621 123456','621 123 456','621 12 34 56','621.12.34.56','675123456','abcdefghr');
//renvoie true true true true true false false
foreach($test as $var)
{
	var_dump($var,preg_match($pattern,$var));echo '<br>';
}
?>

EDIT : 2ème balise PHP modifié pour corriger une faute qui s'y était glissé
Modifié en dernier par Spols le 01 sept. 2010, 22:28, modifié 1 fois.
Spols
pour les fan de rubik's cube ou pour les curieux ==> le portail francophone du rubik's cube

Eléphanteau du PHP | 30 Messages

29 août 2010, 21:47

je proposerais
$pattern = '/^(621|691|661){1}(([[:punct:][:blank:]]{0,1}[0-9]{2}){3}|([[:punct:][:blank:]]{0,1}[0-9]{3}){2})^$/';
code de test :
<?php
$pattern = '/^(621|691|661){1}(([[:punct:][:blank:]]{0,1}[0-9]{2}){3}|([[:punct:][:blank:]]{0,1}[0-9]{3}){2})$/';
echo $pattern.' <br>';
$test = array('621123456','621 123456','621 123 456','621 12 34 56','621.12.34.56','675123456','abcdefghr');
//renvoie true true true true true false false
foreach($test as $var)
{
	var_dump($var,preg_match($pattern,$var));echo '<br>';
}
?>
Tout d'abord, merci pour ton aide et pour tes explications, je comprends mieux.
Par contre il doit y avoir encore une petite erreur car quand je teste, mon formulaire me signale que mon numéro de GSM est faux... est-ce que cela peut venir des ' car dans le reste de mon code j'ai utilisé des " ?

ViPHP
ViPHP | 5462 Messages

29 août 2010, 22:27

tu peux te servir de ce si pour tester tes expressions
http://gskinner.com/RegExr/

Mammouth du PHP | 1967 Messages

29 août 2010, 23:07

l'emploi de ' ou de " ne devrais rien changer du tout, sous quelle format as tu essayer ton numéro de téléphone, ce qui est important, c'est les 3 premier chiffres et comment tu sépare, regroupe les suivants.

Donne nous la séquence de chiffres essayés en changeant les chiffres mais pas les espace et autre ponctuation.

le format donné n'accepte pas : (entre autre)
un 0 avant l'indicatif
un espace ou une ponctuation en fin de ligne
plus d'un espace/ponctuation entre des paires ou trio de chiffres
les chiffres seules

Donne nous un maximum d'exemple de format valide et non valide afin de pouvoir t'aider
Spols
pour les fan de rubik's cube ou pour les curieux ==> le portail francophone du rubik's cube

Eléphanteau du PHP | 30 Messages

31 août 2010, 09:41

l'emploi de ' ou de " ne devrais rien changer du tout, sous quelle format as tu essayer ton numéro de téléphone, ce qui est important, c'est les 3 premier chiffres et comment tu sépare, regroupe les suivants.

Donne nous la séquence de chiffres essayés en changeant les chiffres mais pas les espace et autre ponctuation.

le format donné n'accepte pas : (entre autre)
un 0 avant l'indicatif
un espace ou une ponctuation en fin de ligne
plus d'un espace/ponctuation entre des paires ou trio de chiffres
les chiffres seules

Donne nous un maximum d'exemple de format valide et non valide afin de pouvoir t'aider
Hello Spols,

Merci pour ton aide, par exemple j'ai testé :
621123456
621 123 456
621 12 34 56
mais cela ne marche pas alors que ce genre de format devrait fonctionner :| j'ai dû rater quelque chose :'(

au moins ce qui marche c'est que si je fais des 621621621621 comme avant, le formulaire retourne une erreur.

Mammouth du PHP | 1967 Messages

31 août 2010, 10:40

Donne nous ton code en entier, car quand j'ai essayé les numéros donné dans mon code de test, il me renvoie 1.

Il peut y avoir un problème à l'endroit de l'utilisation du pattern
Spols
pour les fan de rubik's cube ou pour les curieux ==> le portail francophone du rubik's cube

Eléphanteau du PHP | 30 Messages

01 sept. 2010, 17:37

Donne nous ton code en entier, car quand j'ai essayé les numéros donné dans mon code de test, il me renvoie 1.

Il peut y avoir un problème à l'endroit de l'utilisation du pattern
hum un vrai casse tête... j'ai cherché en vain :'(
voilà une partie de mon code :
dans le formulaire : form.php
<?php

if(isset($_POST["valider"]))

{
	require 'checkEntries2.php';
	require 'sendMail1.php';
	//require 'm2.php';
	
	//  données obligatoires :
	$data["name"] = trim($_POST["name"]);
	$data["responsable"] = trim($_POST["responsable"]);
	$data["tel"] = checkEntries(trim($_POST["tel"]), "digit"); 	
	
	$data["gsm"] = checkEntries(trim($_POST["gsm"]), "gsmtest");
	if($_POST["nogsm"])
		$data["gsm"] = trim($_POST["nogsm"]);
	
	$data["mail"] = checkEntries(trim($_POST["mail"]), "mail");
	$data["adresse"] = trim($_POST["adresse"]);
	$data["condition"] = trim($_POST["condition"]);
	// données facultatives :

	$data_option["fax"] = trim($_POST["fax"]);

		
	$erreur = null;
	$erreurs = array('name' => 'dans le nom de l\'organisme demandeur', 
					'responsable' => 'dans le nom du représentant',
					'tel' => 'dans le numéro de téléphone',
					'gsm' => 'dans le numéro gsm',
				
					'mail' => 'dans l\'adresse mail',
				
					'adresse' => 'dans l\'adresse de facturation',

					'condition'=> 'il faut accepter les conditions d\'utilisation');
					
	
					
					
	echo "<p>";
	foreach($data as $key => $value)
	{
		if(empty($data[$key]))
		{
			$erreur = 1;
			echo "Il y a une erreur $erreurs[$key]<br />";
		}
	}
	
	
	
	
	echo "</p>";
	if($erreur != 0)
		echo "<p>Veuillez recommencer.</p>";
	else
	{
		if(sendMail("form3", $data, $data_option))
			echo "Votre demande a été transmise à nos services.Vous allez recevoir un email de confirmation. Vous pouvez fermer la fenêtre.";
		else
			echo "Erreur de transmission, veuillez recommencer.";
	}
	
	if (is_null($erreur)) {
	$mail = $_POST['mail'];

$destinataire = $mail;

$sujet = "Confirmation " ;



$entetes = "From: @";


$message = "bla bla bla ";


mail($destinataire, $sujet, $message, $entetes) ;
	
	}
	

	
}
?>
ensuite voici le code lié à la case GSM :
<p>
			<label for="form3Gsm">GSM :</label>
			<input name="gsm" type="text" id="form3Gsm" onfocus="MM_popupMsg('Merci d\'entrer un num&eacute;ro de GSM valide commen&ccedil;ant par :\r621, 661, 691\r\rCes donn&eacute;es resteront confidentielles et ne seront utilis&eacute;es que pour traiter votre demande.')" value = "<?php if(isset($_POST["gsm"])) echo htmlspecialchars($_POST["gsm"]) ?>" /> 
 
  *  
  <input name="nogsm" type="checkbox" id="nogsm" value="pas de gsm" <?php if (isset($_POST['nogsm'])) echo 'checked = "checked"'?>/>
  Pas de GSM
  </p>
Ensuite mon fichier checkEntries.php (avec la fonction gsmtest).
<?php

function checkEntries($entry, $type, $needed = 1)
{
	if($needed == 1)
	{
		if(empty($entry))
			return null;
	}
	switch($type)
	{
		case "digit" :
		{
			$pattern = "([[:blank:][:punct:][:digit:]])*";
			
			break;
		}
		case "alnum" :
		{
			$pattern = "([[:alnum:]])*";
			break;
		}
		case "alpha" :
		{
			$pattern = "([[:alpha:]])*";
			break;
		}
		case "lower" :
		{
			$pattern = "([[:lower:]])*";
			break;
		}
		case "upper" :
		{
			$pattern = "([[:upper:]])*";
			break;
		}
		case "alnum+" :
		{
			$pattern = "([-_.])*([[:alnum:]])*";
			break;
		}
		case "mail" :
		{
			$pattern = "[[:alnum:]]([-_.]?[[:alnum:]_?])*@[[:alnum:]]([-.]?[[:alnum:]])+\.([a-z]{2,6})";
			break;
		}
		
		
		case "gsmtest" :
		{
			$pattern = '/^(621|691|661){1}(([[:punct:][:blank:]]{0,1}[0-9]{2}){3}|([[:punct:][:blank:]]{0,1}[0-9]{3}){2})^$/';
			break;
		}
		


		default :
		{
			$pattern = $type;
		}
	}
	if(preg_match("'^".$pattern."$'", $entry))
		return $entry;
	else
	{
		if($needed == 1)
			return null;
		else
			return "Non renseigné";
	}
}
?>
Merci beaucoup pour ton aide, peut être que le pb vient des [] #-o