OVH Cloud OVH Cloud

Erreur dans une expression reguliere pour valider un nom de domaine (sans le suffix e)

18 réponses
Avatar
Bruno Baguette
Bonjour,

J'ai un soucis d'expression régulière pour vérifier la validité d'un nom
de domaine (sans le suffixe .be .eu et cie...).

if(preg_match('^(\[A-Z\d-]{1,63}$|^$)',$DomainName)==0)
{
array_push($Errors,'The domain name is invalid !');
}

Visiblement, l'expression régulière que j'ai faite n'est pas bonne.

Je cherche à vérifier que le nom de domaine soit d'une longueur de 1 à
63 caractères et ne soit constitué que de caractères légaux
(alphabétiques, tirets et chiffres).

Est-ce que vous auriez une idée de l'endroit où se situe mon erreur ?

D'avance un grand merci !

--
Bruno BAGUETTE - bouchon@alussinan.org

S'i'n'a è'ne saquî qui n'doit nin mârtchi, è'n mârtch'rè nîn.

--

8 réponses

1 2
Avatar
Daedalus
'#(^[a-z][a-z0-9-]{0,61}[a-z0-9-]$)#i' // i = case-insensitive, a a


Petite correction dans le 2ième exemple
(le symbole - n'est pas valide comme dernier caractère):

'#(^[a-z][a-z0-9-]{0,61}[a-z0-9]$)#i' // i = case-insensitive, a = a

Avatar
Olivier Miakinen
Le 02/11/2004 13:07, Bruno Baguette répondait à J.J.SOLARI :

(^[w][wd-]{0,61}[wd]{1}$)|(^[w]$)|(^$)


J'ai testé ton expression régulière, cependant je recois ce warning avec
cette expression : Warning: Unknown modifier '|'


J'ai deux hypothèses. La première serait qu'il faut une paire de
parenthèses autour pour accepter le '|' : (x|y) au lieu de x|y.
La seconde serait que les ancres de début et de fin ne doivent peut-être
pas être répétées. Par ailleurs, le {1} ne me semble pas très utile.

^([w][wd-]{0,61}[wd]|[w]|)$

Sinon, on peut se passer des '|' puisque le 2e et le 3e choix de
l'alternative sont des sous-ensembles de ce qui précède.

^([w]([wd-]{0,61}[wd])?)?$


Avatar
nano
Olivier Miakinen <om+ wrote:

(^[w][wd-]{0,61}[wd]{1}$)|(^[w]$)|(^$)



^([w]([wd-]{0,61}[wd])?)?$


Olivier,

y'a pas photo... l'élégance force toujours l'admiration :-)

JJS.
--
Anti-spam : <http://public.xdi.org/=jj.solari>



Avatar
nano
Bruno Baguette wrote:

J'ai testé ton expression régulière, cependant je recois ce warning avec
cette expression : Warning: Unknown modifier '|'

Le | étant le séparateur entre les différents termes de l'expression
régulière, je vois mal par quoi je devrais le remplacer.

De plus, cela n'accepte pas le label "levure" ou "yahoo", qui rentrent
pourtant dans le 1er terme de l'expression régulière.
if(preg_match('(^[w][wd-]{0,61}[wd]{1}$)|(^[w]$)|(^$)','levure')==0)
{
array_push($Errors,'The domain name is invalid !');
}


Bruno,

La syntaxe pour la fonction preg_match ne serait-elle pas erronée ?

Essaie avec :

if ( preg_match( "/^([w]([wd-]{0,61}[wd])?)?$/", $chaine ) == 0 )
{...}

Je reprends ici la solution bien plus élégante proposée par Olivier
ailleurs dans le fil :-)

qça,

JJS.
--
Anti-spam : <http://public.xdi.org/=jj.solari>

Avatar
Daedalus
if ( preg_match( "/^([w]([wd-]{0,61}[wd])?)?$/", $chaine ) == 0 )
{...}

Je reprends ici la solution bien plus élégante proposée par Olivier
ailleurs dans le fil :-)



Élégante ou non, cette expression ne remplit pas les fonctions qu'on lui
prétend (au sens du RFC1034), d'après cette expression le nom de domaine
suivant serait accepté: "2_ou_3_erreur_qui_passe_le_test". Pourtant il n'est
pas bon. C'est visiblement une erreur de compréhension de w. Clarification:
w = [a-zA-Z0-9_] ...

Comme j'ai reçu une notification que certains problèmes ont pu empêcher la
publication de certains de mes articles sur ce groupe de discussion, je vais
en profiter pour expliquer à nouveau et plus en détail.

Première partie [w] :
Pour n'obtenir que les lettres soit on définit une classe [a-zA-Z] ou
[^Wd_]
(qui se résumerait par: tout ce qui est w et qui n'est pas d ou _)

Seconde partie [wd-]{0,61} :
Ici le seul problème est que le caractère _ est accepté comme faisant partie
de w,
et le d est totalement superflue puisque que d fait aussi partie de w.
Ici la solution la plus simple reste de faire une classe de caractère
explicite [a-zA-Zd-] ou [a-zd-] avec le "modifier" 'i'.

Troisième partie [wd]:
Ici 2 choses, d est toujours inutile lorsque w est déjà inclus. Mais le
réel problème demeure toujours le _.
Solution simple: [^W_] (qui se résumerait par: tout ce qui est w et qui
n'est pas _)

Finalement, l'élégance c'est très.... élégant, mais encore faut-il que ce
soit efficace.

Comme je ne sais pas si mes articles précédent à ce sujet ont été publié,
voici les 2 variantes que j'avais soumis alors:

if(preg_match('#(^[w][wd-]{0,61}[wd]{1}$)#', $string)==0) // Ajouter
|(^[^Wd_]$)|(^$) si vraiment nécessaire

if(preg_match('#(^[a-z][a-zd-]{0,61}[a-zd])$)#i', $string)==0)// Ajouter
|(^[^Wd_]$)|(^$) si vraiment nécessaire

Parlant délégance, "if(preg_match(...)==0) pourrait être remplacé par
"if(!preg_match(...))".
Mais parfois l'élégance est plutôt subjective

Dae

Avatar
Daedalus
if ( preg_match( "/^([w]([wd-]{0,61}[wd])?)?$/", $chaine ) == 0 )
{...}

Je reprends ici la solution bien plus élégante proposée par Olivier
ailleurs dans le fil :-)



Élégante ou non, cette expression ne remplit pas les fonctions qu'on lui
prétend (au sens du RFC1034), d'après cette expression le nom de domaine
suivant serait accepté: "2_ou_3_erreur_qui_passe_le_test". Pourtant il n'est
pas bon. C'est visiblement une erreur de compréhension de w. Clarification:
w = [a-zA-Z0-9_] ...

Comme j'ai reçu une notification que certains problèmes ont pu empêcher la
publication de certains de mes articles sur ce groupe de discussion, je vais
en profiter pour expliquer à nouveau et plus en détail.

Première partie [w] :
Pour n'obtenir que les lettres soit on définit une classe [a-zA-Z] ou
[^Wd_]
(qui se résumerait par: tout ce qui est w et qui n'est pas d ou _)

Seconde partie [wd-]{0,61} :
Ici le seul problème est que le caractère _ est accepté comme faisant partie
de w,
et le d est totalement superflue puisque que d fait aussi partie de w.
Ici la solution la plus simple reste de faire une classe de caractère
explicite [a-zA-Zd-] ou [a-zd-] avec le "modifier" 'i'.

Troisième partie [wd]:
Ici 2 choses, d est toujours inutile lorsque w est déjà inclus. Mais le
réel problème demeure toujours le _.
Solution simple: [^W_] (qui se résumerait par: tout ce qui est w et qui
n'est pas _)

Finalement, l'élégance c'est très.... élégant, mais encore faut-il que ce
soit efficace.

Comme je ne sais pas si mes articles précédent à ce sujet ont été publié,
voici les 2 variantes que j'avais soumis alors:

if(preg_match('#(^[w][wd-]{0,61}[wd]{1}$)#', $string)==0) // Ajouter
|(^[^Wd_]$)|(^$) si vraiment nécessaire

if(preg_match('#(^[a-z][a-zd-]{0,61}[a-zd])$)#i', $string)==0)// Ajouter
|(^[^Wd_]$)|(^$) si vraiment nécessaire

Parlant délégance, "if(preg_match(...)==0) pourrait être remplacé par
"if(!preg_match(...))".
Mais parfois l'élégance est plutôt subjective

Dae

Avatar
Daedalus
Comme je ne sais pas si mes articles précédent à ce sujet ont été publié,
voici les 2 variantes que j'avais soumis alors:

if(preg_match('#(^[w][wd-]{0,61}[wd]{1}$)#', $string)==0) // Ajouter
|(^[^Wd_]$)|(^$) si vraiment nécessaire


Bon visiblement je suis extrêmement distrait, j'ai posté l'expression que je
tentait de corriger et non l'expression corrigé...

voici donc l'expression réellement corrigé (vraiment cette fois):

if(preg_match('#(^[^Wd_][a-z0-9-]{0,61}[^W_]$)#i', $string)==0)


La deuxième expression utilisant des classe explicite du genre [a-z...] par
contre était correct.

Désolé, il faudra que je porte plus attention.

Dae (embarrassé) ;-)

Avatar
nano
Daedalus wrote:

if ( preg_match( "/^([w]([wd-]{0,61}[wd])?)?$/", $chaine ) == 0 )
{...}

Je reprends ici la solution bien plus élégante proposée par Olivier
ailleurs dans le fil :-)



Élégante ou non, cette expression ne remplit pas les fonctions qu'on lui
prétend (au sens du RFC1034), d'après cette expression le nom de domaine
suivant serait accepté: "2_ou_3_erreur_qui_passe_le_test". Pourtant il n'est
pas bon. C'est visiblement une erreur de compréhension de w. Clarification:
w = [a-zA-Z0-9_] ...


[...]

Daedalus,

Effectivement, gros enlisement, et on retiendra avec profit toute votre
démonstration

Finalement, l'élégance c'est très.... élégant, mais encore faut-il que ce
soit efficace.


Certes :-)

Comme je ne sais pas si mes articles précédent à ce sujet ont été publié,
voici les 2 variantes que j'avais soumis alors:


Je ne les ai pas vu passer.


if(preg_match('#(^[w][wd-]{0,61}[wd]{1}$)#', $string)==0) // Ajouter
|(^[^Wd_]$)|(^$) si vraiment nécessaire


Une coquille sans doute : cette variante est également erronée parce
qu'elle admettrait un label commençant par un chiffre (^[w] ... $)

if(preg_match('#(^[a-z][a-zd-]{0,61}[a-zd])$)#i', $string)==0)// Ajouter
|(^[^Wd_]$)|(^$) si vraiment nécessaire

Parlant délégance, "if(preg_match(...)==0) pourrait être remplacé par
"if(!preg_match(...))".
Mais parfois l'élégance est plutôt subjective


Maintenant en rassemblant toutes les suggestions il doit être possible
d'aboutir à quelque chose d'efficace et élégant (ou concis si on
préfère, les deux allant souvent de pair) :

if ( !preg_match( '/^([a-z]([a-zd-]{0,61}[a-zd])?)?$/i', $chaine ) )
{...}

JJS.

--
Anti-spam : <http://public.xdi.org/=jj.solari>


1 2