expressions régulières preg_match()

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : expressions régulières preg_match()

Re: expressions régulières preg_match()

par Dr@ke » 02 oct. 2009, 22:48

Bon en fait j'ai trouvé, cela n'a rien à voir avec l'encodage mais avec le setlocale().
A la différence près que pour l'UTF-8 faut aussi utiliser l'option \u

Avec l'encodage ISO:
<?php
header('Content-Type: text/html; charset=ISO-8859-1');
setlocale(LC_ALL,'fr_FR.ISO8859-1');
$chaine = 'abcé';
if (preg_match ('#^[[:alnum:]_-]{4,32}$#', $chaine)) {
    echo 'Preg_match: oui <br/>';
}
echo $chaine;
?>
Avec l'encodage UTF-8:
<?php
header('Content-Type: text/html; charset=UTF-8');
setlocale(LC_ALL,'fr_FR');
$chaine = 'abcé';
if (preg_match ('#^[[:alnum:]_-]{4,32}$#u', $chaine)) {
    echo 'Preg_match: oui <br/>';
}
echo $chaine;
?>

Re: expressions régulières preg_match()

par Dr@ke » 02 oct. 2009, 20:48

Bon ben quelque-chose m'échappe alors car:
# \w Tout caractère "de mot" [a-z0-9_] plus les accentués
# \W Tout autre caractère qu'un caractère "de mot"

Re: expressions régulières preg_match()

par Zahnzao » 02 oct. 2009, 20:39

Pas mal !
J'ai testé ta regex Dr@ke.

C'est très spécial, ca fait a peu près la meme chose. Très étrange il accepte toute ponctuation mais pas trop de consécutifs. Il prend les crochets et accolades, double et simple quotes. Ca peut être intéressant.

Merci, je vais faire quelques test et je verrai si je la garde ou si je repasse a l'autre.

edit: bah en fait il prend quasi tout les caractères, c'est juste dans leur utilisation qu'ils sont limités. Pourtant la description de cette classe dit: tout les caractères pouvant faire partie d'un mot... bizarre

Re: [Résolu] expressions régulières preg_match()

par Dr@ke » 02 oct. 2009, 19:55

http://www.ilu.be/wiki/Aide-memoire_des_regex
u masque UTF-8
Et ne pas confondre avec l'option /U (majuscule)

Je ne connaissais pas non plus cette option :wink:

http://www.php.net/manual/fr/reference. ... ifiers.php
u (PCRE8)
Cette option désactive les fonctionnalités additionnelles de PCRE qui ne sont pas compatibles avec Perl. Les chaînes sont traitées comme des chaînes UTF-8. Cette option est disponible en PHP 4.1.0 et plus récent sur plate-forme Unix et en PHP 4.2.3 et plus récent sur plate-forme Windows.
[EDIT]
Peux-tu tester cette reg?:
preg_match ('#\w#u', $chaine);
Ou celle-ci qui fera l'opération inverse et donc sera pt moins gourmande en ressources:
preg_match ('#\W#u', $chaine);

Re: expressions régulières preg_match()

par Zahnzao » 02 oct. 2009, 19:39

=D>

C'était si simple ....

Je venais justement de passer mes pages en ISO et ca marchais aussi, mais je préfère resté en utf-8.

Un grand merci a vous tous.

Sinon qu'est ce qui a changé avec ce caractère en plus ? je ne comprend pas tres bien.

:cry: j'ai parlé trop vite: Warning: preg_match() Compilation failed: invalid UTF-8 string at offset 33 in C:\......\.php on line 20.

Mais c'st un bon début.

edit: Ca y'est, 2,3 caractères une peu récalcitrant mais finalement pas tres important. Merci !

Re: expressions régulières preg_match()

par Victor BRITO » 02 oct. 2009, 19:27

Et en essayant l'option de recherche u, qu'est-ce que ça donne ?
$test_chaine = preg_match ('#^[^\#\^\$\(\)\[\]\{\}\+\*\\\|<>&@"²³%µ]{9,50}$#u', $chaine);

Re: expressions régulières preg_match()

par Zahnzao » 02 oct. 2009, 19:19

Re bonsoir.

Je viens de m'appercevoir d'un problème qui est très gênant.

Avec cette regex
$test_chaine = preg_match ('#^[^\#\^\$\(\)\[\]\{\}\+\*\\\|<>&@"²³%µ]{9,50}$#', $chaine);
j'entre 50 "a" dans mon champ, pas de probleme. (50 caractères)
si j'entre des "é" ils comptent pour 2 caractères et donc si j'en écris 26 le preg_match() me bloque.

j'ai essayé avec tout les types de caractères accentués, il comptent tous pour 2 caractères....

une idée ??

Pour info je suis en local sous easyphp.

Re: expressions régulières preg_match()

par Dr@ke » 02 oct. 2009, 18:49

Ok mais ne pas confondre encodage et conversion de caractères spéciaux avec htmlentities() ou htmlspecialchars().
Tout en présisant que htmlspecialchars() ne convertit pas les caractères accentués..

Re: expressions régulières preg_match()

par Zahnzao » 02 oct. 2009, 18:30

Apparemment le problème se montre surtout, je croie, avec l'encodage UTF-8.
Je crois que le soucis viens de la. Parceque la chaine directement dans une variable puis traitée avec preg_match() passe sans soucis, alors que les données issues du formulaire (la même chaine donc sans traitement au préalable avec htmlentities() ou htmlspecialchars() ) ne passe pas.

Re: expressions régulières preg_match()

par Dr@ke » 02 oct. 2009, 17:26

Oui je me suis aperçue de cela il n'y a pas très longtemps.
L'utilisation d'expressions régulières en prenant en compte les caractères accentués complique énormément le filtre.

Même chose avec la fonction ctype().
(Précision; c'était pour trouver une fonction ctype() acceptant les caractères accentués mais pas les autres caractères spéciaux et pas les retour à la ligne -> je n'ai pas réussis avec cette méthode).

Apparemment le problème se montre surtout, je croie, avec l'encodage UTF-8.

Ca devient un vrai casse-tête quand tu veux faire un filtre efficace prenant en compte les caractères accentués mais n'acceptant pas les autres caractères spéciaux.

Maintenant je ne sais pas si cela était la raison de ton soucis, mais cela m'a fait pensé a cela...

Ps:
je précise que c'est compliqué pour moi, pour les autres je ne sais pas :wink:


[EDIT]
L'explication a cela, est peut-être que dans la langue de Shakespear -> il n'y a pratiquement pas de caractères accentués.
Enfin c'est ma propre déduction...

[EDIT 2]
D'ailleurs si quelqu'un a une méthode simple -> je suis preneur aussi :)

Re: expressions régulières preg_match()

par Zahnzao » 02 oct. 2009, 16:55

non il n'y avait rien de tout ca, mon code était tel que je l'ai mis ici.

Du coup j'ai tout modifié. Au lieu de mettre dans la regex les caractères acceptés, j'ai exclu ceux que je ne voulais pas ... ca raccourcis mon code et c'est plus clair :p surtout que je me suis rendu compte qu'il me fallait finalement les chiffres ... alors tant qu' a faire...
preg_match ('#^[^\#\^\$\(\)\[\]\{\}\+\*\\\|<>&@"²³%µ]{9,100}$#', $chaine);
Merci pour votre aide ;)

Re: expressions régulières preg_match()

par jojolapine » 02 oct. 2009, 16:02

Tu es sûr que tu n'as pas un htmlentities() ou htmlentities() qui traine?
parce que si enlever [:punct:] fait que les accents ne sont plus acceptés, ça m'étonnerais pas, qu'ils soient transformé en &eacut; ou autre...

Re: expressions régulières preg_match()

par Zahnzao » 02 oct. 2009, 12:38

Ca marche !

donc ca venait de l'expression... Par contre le [:punct:] accepte beaucoup trop de cractères a mon gout :( et si je je l'enlève, il ne prend plus plus mes éèà et tout le tralala ... je vais essayer de les exclures par la suite.

j'ai aussi remplacé le alnum par alpha car je ne veux pas de chiffres.

Merci à toi ;)

Re: expressions régulières preg_match()

par Victor BRITO » 02 oct. 2009, 12:26

Essaie avec l'expression rationnelle suivante :
preg_match ('#^[[:alnum:][:space:][:punct:]]{9,70}$#', $chaine);
Cela dit, ma suggestion précédente est toujours bonne à prendre et t'évitera des désagréments liées aux \. ;)

Re: expressions régulières preg_match()

par Zahnzao » 02 oct. 2009, 12:06

Non pas de \ dans la chaine récupérée. J'ai quand même testé et ca ne change rien.

pour expliquer plus clairement.

Le champ apercu était créer dynamiquement par un script javascript. c'était en fait la concaténation de 8 champs. Pensant que ca venait de la, j'ai un peu modofié mon script de manière a concaténer les champs en php sans récuperer le champ apercu.
if(isset($_POST['submit']))
	{
	$chaine=$_POST['mot1'].$_POST['ponctuation1']." ".$_POST['mot2'].$_POST['ponctuation2']." ".$_POST['mot3'].$_POST['ponctuation3']." ".$_POST['mot4'].$_POST['ponctuation4'];
	echo $chaine;
	if(preg_match("#^[a-zA-Zàçèéê ',.:-]{9,70}$#",$chaine))
		{
		echo"<p>Les champs sont bien remplis.</p>";
		}
	else
		{
		echo"<p>Les champs sont mal remplis.</p>";
		}
	}
De cette manière, les données envoyées sont écrite manuellement et non issues de variables Javascript.
Mais malheureusement ca ne change rien. Il refuse systématiquement tout mes (à ç è é ê).

edit: mon echo renvoie exactement la chaine telle quelle, c'est la que je comprend pas ... je suis perdu. Et ma regex passe sans problemes sur plusieurs testeurs en ligne dispo sur le net ...