Aide pour regex

Aide pour regex - Divers - Programmation

Marsh Posté le 08-03-2018 à 18:30:10    

Hello
 
Je me prends la tete avec REGEX et j'avoue qu'un coup de main serait le bien venu !
 
Je cherche a filtrer (en powershell) une chaine de caractere qui est a la base une url.
 
Mon test consiste a :
- exclure les urls commencant par : "http://" "https://" "http" "https" "www."
- exclure les urls finissant par "."
- exclure les urls ne finissant pas par ".xxxxxxx"
 
exemples :
Non valides
.google
www.go.fr
google
.google.
http://test.google.fr
https://test.google.fr
http://www.google.fr
 
Valides
wwww.fr.fr
.google.dr
google.fr
wwwwwwwww.fr
w.google
.google.com
ww.xxxx.xx
bb.xxxx.xxx
ccc.google.fr
.challengeprice.com/system/
.digitalforce.co.il
.ifferfsodp9ifjaposdfjhgosurijfaewrwergwea.com
10.0.0.1
 
J'ai bien un regex qui s'en rapproche mais je n'arrive pas a exclure les urls qui commencent par "www."
 
Ma regex :  

Code :
  1. ^(([a-zA-Z0-9)]+\.[^\s]{2,})|\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|(?:\.|(?!))[a-zA-Z0-9]\.[^\s]{2,}|\.[a-zA-Z0-9]\.[^\s]{2,})$


 
Merci a la bonne âme qui passera par la avec une solution sinon une aide :)
 
Merci

Reply

Marsh Posté le 08-03-2018 à 18:30:10   

Reply

Marsh Posté le 08-03-2018 à 20:39:45    

C'est la saison des Regex ?

 
Code :
  1. ^(?!http:\/\/)^(?!https:\/\/)^(?!www\.).+(?:\..+)$


Message édité par MaybeEijOrNot le 08-03-2018 à 20:42:19

---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
Reply

Marsh Posté le 09-03-2018 à 08:20:13    

Merci a toi !
Beaucoup plus simple que la mienne ^^ et en plus fonctionnelle :)
 
Question subsidiaire :
Si l'url commence par autrechose qu'une lettre ou un chiffre est ce que l'on peut verifier que ce premier caractere est un point ? histoire d'exclure de possible mauvaise saisie comme ';google.fr'
 
Merci


Message édité par orlith le 09-03-2018 à 08:28:34
Reply

Marsh Posté le 09-03-2018 à 08:59:26    

Je crois que j'ai trouvé :
^(?!http:\/\/)^(?!https:\/\/)^(?!www\.)^([a-z$%&.]).+(?:\..+)$
 
Merci


Message édité par orlith le 09-03-2018 à 11:30:36
Reply

Marsh Posté le 09-03-2018 à 11:30:21    

Mince ce que j'ai rajouté invalide la possibilite d'une url avec un seul caractere
 
f.fr n'est plus valide (certe une url a un caractere ne coure pas les rues mais sait on jamais)
Qu'elle est mon erreur ?
 
merci

Reply

Marsh Posté le 09-03-2018 à 17:56:28    

Solution :

Code :
  1. ^(?!http:\/\/)^(?!https:\/\/)^(?!www\.)^(?=[a-z0-9$%&.]).+(?:\..+)$
 

Dans ton exemple le "w.google" ne fonctionnait pas car dans ton expression régulière :

Code :
  1. ^([a-z$%&.])


capture le premier caractère, et on dit ensuite qu'on veut n'importe quel caractère (au moins une fois) suivi d'un point et de n'importe quel caractère (au moins une fois).

 


Donc :

Code :
  1. ^(?!http:\/\/)^(?!https:\/\/)^(?!www\.)^([a-z$%&.])


capture "w",

 


Code :
  1. (?:\..+)$


capture ".google",

 


Code :
  1. .+


il n'y a plus rien à capturer or on demande de capturer n'importe quel caractère au moins une fois donc ça échoue.

 


La solution c'est donc de faire une assertion qui va tester ce qu'il y a devant sans déplacer le pointeur (je t'ai ajouté les chiffres pour les IPs) :

Code :
  1. ^(?=[a-z0-9$%&.])


Message édité par MaybeEijOrNot le 09-03-2018 à 17:58:52

---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
Reply

Marsh Posté le 09-03-2018 à 18:25:43    

Merci pour l'explication detaillée ! Ca reste quand meme obscur le regex ^^
Va vraiment falloir que je m'y mette sérieusement car ca simplifie quand meme les choses ! Je vais voir pour des formations en ligne :)
 
Merci bcp !

Reply

Marsh Posté le 09-03-2018 à 18:51:44    

Perso je n'ai pas fait de formation, j'utilise peu les expressions régulières. Cela peut devenir compliqué quand tu te tournes vers de la récurrence.
Mais de manière générale tu as toujours moyen d'arriver facilement au résultat voulu en découpant en plusieurs étapes. C'est souvent plus lisible et même plus performant.


---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
Reply

Marsh Posté le 12-03-2018 à 15:21:41    

Hello @MaybeEijOrNot
 
Un testeur a rentré "l'url" suivante pour tester : ...pleaseblockme.dkdk ou ..pleaseblockme... et c'est passé.
J'ai essayé de faire en sorte d'exclure les mots ".." mais je n'y arrive pas.
J'ai essayé un negative lookahead comme pour HTTP ^(?!..) mais j'ai l'impression qu'il fonctionne en mode "caractere" et pas "mots"  
J'ai essayé de lui dire d'exclure les urls dont au moins 2 points se suivent, mais la je pense que je n'ai pas reussi a écrire la requete ^^  
 
Il faudrait aussi que je reussisse ou comprenne comment exclure les urls ou il y a un "espace", j'ai vu qu'il fallait jouer avec /S, et celle au format email ou il y a un '@'
Ah tiens on vient de me dire qu'une url du genre google.fr. passe :(
La ca se complexifie, du coup si ca t'ennuie n'hesites pas je rajouterai des filtres avec powershell plutot qu'ne regex
 
Merci et desolé de t'embeter .


Message édité par orlith le 12-03-2018 à 15:55:22
Reply

Marsh Posté le 12-03-2018 à 20:53:41    

Salut,
 
Dans la mesure où tu ne connais pas à l'avance le nombre de points qui peuvent être utilisés, oui ça va être compliqué. Cela implique de passer par de la récursivité, je ne sais même pas si les regex sur powershell acceptent la récursivité. Mais c'est typiquement le cas où à moins d'avoir une récursivité triviale, tu vas demander au script de faire un grand nombre d'itération inutiles.
 
Le point dans une regex a deux sens, celui de grosso modo n'importe quel caractère, ou celui du point au sens propre. Quand on veut lui donner le sens du point en tant que tel on est obligé de l'échapper avec un anti-slash sauf lorsqu'il est placé entre crochets.
 
 
Cette expression ne capture pas les adresses avec des espaces et celles qui finissent avec un point :

Code :
  1. ^(?!http:\/\/)^(?!https:\/\/)^(?!www\.)^(?=[a-z0-9$%&.])\S+(?:\.\S+[^.])$


 
Pour la répétition du point et l'arobase il faut que je réfléchisse, mais pas ce soir, désolé.


---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
Reply

Marsh Posté le 12-03-2018 à 20:53:41   

Reply

Marsh Posté le 12-03-2018 à 21:37:44    

Deja ca m'aide pas mal :) Je voyais bien qu'il prenait le point comme un wildcard.
Merci et bonne soirée.

Reply

Marsh Posté le 13-03-2018 à 13:43:26    

Et voilà un truc bien dégueu :

 
Code :
  1. ^(?!http:\/\/)^(?!https:\/\/)^(?!www\.)(?(?=\.)(?:(?:\.[^\r\n\t\f\v @.]+)+(?:\.[^\r\n\t\f\v @.]+)$)|(?:(?:[^\r\n\t\f\v @.]+\.)+(?:[^\r\n\t\f\v @.]+)$))
 

Sans récursion au final, il suffit d'ajouter les caractères interdits dans les parties avec crochets.


Message édité par MaybeEijOrNot le 13-03-2018 à 13:45:03

---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
Reply

Marsh Posté le 13-03-2018 à 14:47:29    

Wow j'essaierai meme pas de le comprendre celui ci :)
 
Merci pour ton aide precieuse !

Reply

Marsh Posté le 13-03-2018 à 20:31:05    

Faut juste bien découper pour comprendre, d'ailleurs en la découpant j'ai trouvé une simplification dans son écriture (pas dans son fonctionnement) :

Code :
  1. ^(?!http:\/\/)^(?!https:\/\/)^(?!www\.)(?(?=\.)(?:\.[^\r\n\t\f\v @.]+){2,}$|(?:(?:[^\r\n\t\f\v @.]+\.)+(?:[^\r\n\t\f\v @.]+)$))


 
Le début, comme avant, on exclue les termes par lesquels on ne veut pas que ça commence :

Code :
  1. ^(?!http:\/\/)^(?!https:\/\/)^(?!www\.)


 
Ensuite :

Code :
  1. (?(?=\.)


Si (c'est ce que signifie le premier point d'interrogation) ça commence par un point alors on cherche une expression du genre suivant :

Code :
  1. (?:\.[^\r\n\t\f\v @.]+){2,}$


C'est à dire un point suivi des caractères non interdits (espacements, arobase et point), le tout devant être répété au moins une fois (soit présent au moins deux fois) et que ça se finisse par ce motif.
Sinon (ce que signifie la barre verticale) on cherche une expression de la forme suivante :

Code :
  1. (?:(?:[^\r\n\t\f\v @.]+\.)+(?:[^\r\n\t\f\v @.]+)$)


C'est à dire des caractères non interdits (espacements, arobase et point) suivi d'un point, ceci devant être répété au moins une fois puis suivi de caractères non interdits (espacements, arobase et point) jusqu'à la fin.
 
Petit rappel, "(?:...)" signifie qu'on crée un groupe non capturant, son but c'est donc de bénéficier de l'intérêt des parenthèses (créer un groupe) sans avoir à capturer ce dit groupe (comportement par défaut des parenthèses). Et "(?=...)" est une assertion positive, c'est à dire qu'on regarde ce qu'il y a devant sans déplacer le pointeur.
 
 
Néanmoins j'ai deux remarques, au lieu d'utiliser des caractères interdits, des caractères autorisés seraient probablement plus appropriés. Par exemple, dans le regex proposé, des caractères accentués sont autorisés alors qu'il n'y en a pas normalement dans un host. Je ne connais pas les règles exactes, mais je pense que tu es tout autant capable que moi de les trouver.
La deuxième remarque concerne plus la finalité, si le but c'est résoudre une adresse, pourquoi interdire le protocole et/ou le "www" ? Ok ça ne fait pas parti de l'adresse mais si l'utilisateur rentre "https://www.google.fr" on se doute bien qu'il veut résoudre "google.fr", pourquoi lui renvoyer une erreur dans sa face quand on pourrait gentiment lui faire le boulot en lui faisant à la limite remarquer qu'on résout l'adresse "google.fr" ?


---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
Reply

Marsh Posté le 19-03-2018 à 18:34:12    

merci bcp pour ce detail

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed