IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

problème avec re.search [Python 3.X]


Sujet :

Python

  1. #1
    Membre chevronné
    Homme Profil pro
    BTS SN IR
    Inscrit en
    Mai 2017
    Messages
    514
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : BTS SN IR

    Informations forums :
    Inscription : Mai 2017
    Messages : 514
    Par défaut problème avec re.search
    Bonjour,
    je galère avec les regex .. et je ne comprend pas où est l'erreur

    Les conditions :
    • taille comprise entre 2 et 20 caractères
    • majuscule possible uniquement en début de pseudo
    • pas de caractères spéciaux sauf "-" à ne pas placer en fin de pseudo, 2max
    • 2 lettres identiques successives max



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    if not pseudo:
    errors.append("erreur : pseudo non renseigné")
    else:
    if not len(pseudo) in range(2, 20):
    	if len(pseudo)<2:
    		errors.append("erreur : pseudo trop court")
    	elif len(pseudo)>20:
    		errors.append("erreur : pseudo trop long")
    if re.match("^[\a]?(-?[:lower:]+){0,2}$", pseudo):
    	errors.append("erreur : pseudo invalide")
    else:
    	for i in range(len(pseudo)-2):
    		if pseudo[i]==pseudo[i+1]==pseudo[i+2]:
    			errors.append("erreur : pseudo invalide")
    mais par exemple 'A-' est valide et 'a--a-a-a-a-a-a' l'est aussi ..

  2. #2
    Membre très actif

    Homme Profil pro
    Bidouilleur
    Inscrit en
    Avril 2016
    Messages
    721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bidouilleur

    Informations forums :
    Inscription : Avril 2016
    Messages : 721
    Billets dans le blog
    1
    Par défaut
    Salut,

    Je n'ai pas compris pourquoi 'a--a-a-a-a-a-a' ne serait pas valide, selon tes conditions, cela devrait l'être, ou alors j'ai mal saisi quelque chose.

    Sans re, j'aurais fait ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    import itertools
     
    def test_pseudo(pseudo) :
        mes = None
        if not 2 <= len(pseudo) <= 20 :
            mes = 'longueur du pseudo'
        elif not pseudo[1:].islower() :
            mes = 'majuscule dans le pseudo'
        elif [c for c in pseudo.lower() if ord(c) not in list(range(97, 123)) + [45]] :
            mes = 'Caractères non autorisés'
        elif pseudo[-1] == '-' :
            mes = '- en fin de pseudo'
        elif [n[0] for n in itertools.groupby(pseudo) if len(tuple(n[1])) > 2] :
            mes = 'répétition de caractères'
        return mes
     
    for p in ('bob'*7, 'bOb', 'Bob-', 'bo_b', 'Booob', 'Bob-bob', 'bo') :
        print(p, test_pseudo(p))

  3. #3
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Je ne suis pas un spécialiste des regex, mais voilà ce que j'ai trouvé, en fonction de ce que j'ai compris de tes conditions:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    motif1 = r"^[a-zA-Z][a-z\-]{0,18}[a-z]$"
    motif2 = r"([a-z\-])\1{2,}"
     
    ch = r"A--a-a-a-a-a-a"
    ok = re.match(motif1, ch)!=None and re.search(motif2, ch)==None
    print(ok)
    True
    Le search avec le motif2 doit échouer pour qu'on sache qu'il n'y a jamais plus de 2 caractères identiques consécutifs. Par exemple, ch = r"A--a-aaa-a-a-a-a" échouera.

    Vérifie que ça colle avec toutes tes conditions.

  4. #4
    Membre chevronné
    Homme Profil pro
    BTS SN IR
    Inscrit en
    Mai 2017
    Messages
    514
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : BTS SN IR

    Informations forums :
    Inscription : Mai 2017
    Messages : 514
    Par défaut
    Merci de vos réponses,
    J'ai ça pour l'instant comme regex r"^[a-zA-Z][a-z]*-?[a-z]+-?[a-z]+$" mais il faut au moins 3 caractères, le seul moyen est de faire r"^[a-zA-Z][a-z]*-?[a-z]+-?[a-z]*$" et séparément vérifier que pseudo[-1:] != "-".

    Existe t'il un moyen en regex de faire des conditions ?
    Du style si y'as "-" il doit obligatoirement y avoir un caractère après ? plutôt que de faire il y a 0 ou 1 "-" et après 1 ou plus caractères.

  5. #5
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Essaie ma solution, puisqu'elle répond à ta dernière question (pas de '-' à la fin).

    Par contre, s'il doit y avoir 3 caractères mini (tu avais dit 2 dans tes conditions), dans mon motif1, il faut corriger le {0,18} => {1,18}.

    Et dans ton motif, tu as oublié le '-', mais même en le corrigeant de ça, il ne marche pas (il devrait refuser r"A--a-a-aaa-a-a-a"). Pour ma part, je n'ai pas trouvé de solution pour tester "pas plus de 2 caractères identiques consécutifs" dans un seul motif.

  6. #6
    Membre très actif

    Homme Profil pro
    Bidouilleur
    Inscrit en
    Avril 2016
    Messages
    721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bidouilleur

    Informations forums :
    Inscription : Avril 2016
    Messages : 721
    Billets dans le blog
    1
    Par défaut
    Faire tout avec une expression complexe, je ne sais pas si c'est vraiment une bonne solution à adopter, car c'est difficilement lisible, et encore plus si on revient beaucoup plus tard sur notre code.

    Quelque chose qui pourrait tendre vers ce que tu veux :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    reg = re.compile(r'^(?!-)([A-Z])?(([a-z-])(?!\3{2,})){2,19}(?(1)|[a-z])(?<!-)$')
     
    for p in (
        'Bo',
        'bo',
        'bob',
        'Booo',
        'bbb',
        'bo'*9 + 'b',
        'bo'*10,
        'bo'*9 + 'b-',
        'bob'*7,
        'Bob-',
        '-bob',
        'bob-bob',
        'Bob',
        '-Bob',
        'bob---bob',
    ) :
        print(p, len(p), bool(reg.match(p)))
    Pas sûr que ça concorde bien avec tous tes critères.

    Mais ça reste tout de même imbitable.

  7. #7
    Membre chevronné
    Homme Profil pro
    BTS SN IR
    Inscrit en
    Mai 2017
    Messages
    514
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : BTS SN IR

    Informations forums :
    Inscription : Mai 2017
    Messages : 514
    Par défaut
    Bonjour,
    J'ai finalement réussi à faire se que je voulait, merci bistouille de m'avoir mis sur la voie avec les ?!,
    voici mon code final:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    if not pseudo:
    	errors.append("erreur : pseudo non renseigné")
    else:
    	if not len(pseudo) in range(2, 20):
    		if len(pseudo)<2:
    			errors.append("erreur : pseudo trop court")
    		elif len(pseudo)>20:
    			errors.append("erreur : pseudo trop long")
    	if not re.match(r'[a-zA-Z](-?[a-z]+){0,2}$', pseudo):
    		errors.append("erreur : pseudo invalide")
    	else:
    		for i in range(len(pseudo)-2):
    			if pseudo[i]==pseudo[i+1]==pseudo[i+2]:
    				errors.append("erreur : pseudo invalide")
    Bon je trouve que le test de conditions est ni trop long ni trop incompréhensible, si jamais quelqu'un voit une amélioration à faire je suis preneur d'idée

  8. #8
    Membre très actif

    Homme Profil pro
    Bidouilleur
    Inscrit en
    Avril 2016
    Messages
    721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bidouilleur

    Informations forums :
    Inscription : Avril 2016
    Messages : 721
    Billets dans le blog
    1
    Par défaut
    Salut,

    La 1ère chose à rectifier est ton range pour vérifier la longueur qui ne sert strictement à rien puisque tu vérifies la longueur min et max.
    La seconde, est dans la vérification des caractères consécutifs, il faut un break, sinon en cas de saisie de pseudo comme toooooooooooto, tu vas te retrouver avec la même erreur ajoutée x fois, perso, là j'aurais tout testé dans une expression, mais le principal est que ça fonctionne.

    Aussi tant qu'à faire autant ne calculer qu'une seule fois la longueur du pseudo, bon, c'est une optimisation infinitésimale, mais c'est toujours mieux d'éviter d'appeler la même méthode à plusieurs reprises si on peut l'éviter.

    Par contre, je n'ai pas compris ce qu'est censé faire [a-zA-Z](-?[a-z]+){0,2}, pourquoi 0,2 ? Cela signifie qu'il peut y avoir au maximum 2 tirets dans la chaine ?

  9. #9
    Membre chevronné
    Homme Profil pro
    BTS SN IR
    Inscrit en
    Mai 2017
    Messages
    514
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : BTS SN IR

    Informations forums :
    Inscription : Mai 2017
    Messages : 514
    Par défaut
    Citation Envoyé par bistouille Voir le message
    Par contre, je n'ai pas compris ce qu'est censé faire [a-zA-Z](-?[a-z]+){0,2}, pourquoi 0,2 ? Cela signifie qu'il peut y avoir au maximum 2 tirets dans la chaine ?
    oui, c'était le but enfaite à la base
    Les conditions :
    taille comprise entre 2 et 20 caractères
    majuscule possible uniquement en début de pseudo
    pas de caractères spéciaux sauf "-" à ne pas placer en fin de pseudo, 2max
    2 lettres identiques successives max

  10. #10
    Membre très actif

    Homme Profil pro
    Bidouilleur
    Inscrit en
    Avril 2016
    Messages
    721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bidouilleur

    Informations forums :
    Inscription : Avril 2016
    Messages : 721
    Billets dans le blog
    1
    Par défaut
    Ah, ok, j'avais pas fait attention au 2 tirets max.

    Dans ce cas, un pseudo comme toto-toto-toto ne passe pas ton expression doit-être modifiée

  11. #11
    Membre chevronné
    Homme Profil pro
    BTS SN IR
    Inscrit en
    Mai 2017
    Messages
    514
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : BTS SN IR

    Informations forums :
    Inscription : Mai 2017
    Messages : 514
    Par défaut
    En effet j'ai encore fait n'importe quoi ... x)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
     
    def __init__(self):
    	adress = QtWidgets.QLineEdit()
    	layout.addWidget(QtWidgets.QLabel(text="adresse :"), 0, 0)
    	layout.addWidget(adress, 0, 1)
     
    	port = QtWidgets.QSpinBox(minimum=1, maximum=655350, objectName="port")
    	port.valueChanged.connect(lambda value: port.setValue(port.maximum()/10) if value > port.maximum()/10 else None)
    	layout.addWidget(QtWidgets.QLabel(text="port :"), 1, 0)
    	layout.addWidget(port, 1, 1)
     
    	pseudo = QtWidgets.QLineEdit()
    	pseudo.setValidator(QtGui.QRegExpValidator(QtCore.QRegExp(r'[a-zA-Z](-?[a-z]+){,3}$')))
    	layout.addWidget(QtWidgets.QLabel(text="pseudo :"), 2, 0)
    	layout.addWidget(pseudo, 2, 1)
     
    	button_connect = QtWidgets.QPushButton(text="Connexion")
    	button_connect.clicked.connect(lambda: self.connect(adress.text().strip(), port.value(), str(pseudo.text().strip())))
    	layout.addWidget(button_connect, 4, 0, 1, 2)
     
    def connect(self, adress, port,  pseudo):
    	errors = []
    	if not IP:
    		errors.append("erreur : IP non renseignée")
    	if not pseudo:
    		errors.append("erreur : pseudo non renseigné")
    	else:
    		if len(pseudo)<2:
    			errors.append("erreur : pseudo trop court")
    		elif len(pseudo)>20:
    		errors.append("erreur : pseudo trop long")
    		elif pseudo[:-1] == "-":
    			errors.append("erreur : pseudo invalide")
    		else:
    			for i in range(len(pseudo)-2):
    				if pseudo[i]==pseudo[i+1]==pseudo[i+2]:
    					errors.append("erreur : pseudo invalide")
    J'ai préféré me passer du module re et passer directement par un QRedExp, vaut mieux prévenir que guérir comme le dit le proverbe

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème avec Search Dialog
    Par ecplusplus dans le forum Composants graphiques
    Réponses: 0
    Dernier message: 22/06/2015, 17h11
  2. [SP-2007] Problème avec People Search
    Par Rickz dans le forum SharePoint
    Réponses: 10
    Dernier message: 09/06/2010, 13h47
  3. Problème avec "Java Search" dans les JSP
    Par B@tman dans le forum Eclipse Java
    Réponses: 0
    Dernier message: 08/01/2008, 11h57
  4. problème avec search.daily
    Par looping dans le forum Windows XP
    Réponses: 0
    Dernier message: 31/12/2007, 09h20
  5. Problème avec la mémoire virtuelle
    Par Anonymous dans le forum CORBA
    Réponses: 13
    Dernier message: 16/04/2002, 16h10

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo