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

VB.NET Discussion :

[VB2008 | Regex] Comment faire une regex sur une chaine verifiant l'unicité des caractères qui la composent


Sujet :

VB.NET

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Août 2005
    Messages
    483
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 483
    Points : 309
    Points
    309
    Par défaut [VB2008 | Regex] Comment faire une regex sur une chaine verifiant l'unicité des caractères qui la composent
    Bonjour,

    N'étant pas très doué avec l'outil puissant que sont les expressions régulière, je viens vous demander de l'aide :

    J'aimerai vérifier dans une chaine de caractère composé uniquement de caractère [A-Z], qu'il n'y ais pas 2 fois le même caractère dans la chaine. La taille de la chaine peut etre variable :

    AA => incorrect
    ABCDFG => correct
    ABBDFG=> incorrect

    Est-ce possible avec les expressions régulières?

    merci d'avance pour votre aide

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Je ne pense pas qu'on puisse faire ça avec les regex... mais tu peux le faire avec Linq, en exploitant le fait que String implémente IEnumerable(Of Char) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Dim s As String = ...
    If s.Where(AddressOf Char.IsLetter).Distinct().Count() = s.Length Then
        ' correct
    Else
        ' incorrect
    End if

  3. #3
    Membre actif
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2010
    Messages
    151
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Novembre 2010
    Messages : 151
    Points : 254
    Points
    254
    Par défaut
    Citation Envoyé par tomlev Voir le message
    Je ne pense pas qu'on puisse faire ça avec les regex... mais tu peux le faire avec Linq, en exploitant le fait que String implémente IEnumerable(Of Char) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Dim s As String = ...
    If s.Where(AddressOf Char.IsLetter).Distinct().Count() = s.Length Then
        ' correct
    Else
        ' incorrect
    End if
    Très jolie méthode.

    Je ne pense pas non plus que ce soit possible avec les regex, les regex peuvent être utilisées pour représenter des Automates d'Etats Finis or ce que tu souhaites ici relève plus de l'Automate à Pile (selon moi).
    Pensez au et un petit vote si mon post vous a été utile .

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Août 2005
    Messages
    483
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 483
    Points : 309
    Points
    309
    Par défaut
    Bonjour,

    et merci pour vos réponse.

    Cependant je ne sais pas comment utiliser link.

    Et il couine sur le where.

    Que faut-il pour utiliser link?

    les regex peuvent être utilisées pour représenter des Automates d'Etats Finis or ce que tu souhaites ici relève plus de l'Automate à Pile (selon moi).
    J'ai lu cette article ou il parle des automate à pile. Et il présente des regex sur ces derniers. Même si j'ai pas tout compris, il semble possible de pouvoir faire des regex sur des automate à pile? ou alors j'ai rien compris???

    merci pour votre aide.

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par narutobaka Voir le message
    Cependant je ne sais pas comment utiliser link.

    Et il couine sur le where.

    Que faut-il pour utiliser link?
    Ajoute une référence à System.Core.dll (si elle n'est pas déjà là)
    Et ajoute un Imports au début du fichier :


  6. #6
    Membre chevronné
    Avatar de Sehnsucht
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2008
    Messages
    847
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Lot et Garonne (Aquitaine)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Octobre 2008
    Messages : 847
    Points : 2 209
    Points
    2 209
    Par défaut
    Bonjour,

    Alors, juste pour le fun j'ai cherché à résoudre ça en regex et je suis parvenu je me suis grandement inspiré (euphémisme ) de ceci, ce qui donne lieu à deux solutions.
    Enfin j'ai pas trop poussé les tests donc je garantis pas l'efficacité sur tous les cas et de toute façon :
    • c'est dur à déchiffrer (enfin encore plus qu'une regex "classique" )
    • question perf c'est (en moyenne) pas trop ça
    mais bon je les mets quand même
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    "^(?:([A-Z])(?=(?:(?!\1)[A-Z])*$)[A-Z]*?){#}"
    "^(?>([A-Z])(?:(?<=\1[A-Z]+))|(?<distinct>[A-Z]))+$(?<-distinct>){#}"
    Note: dans les deux cas # est à remplacer par la longueur de la chaîne à tester.

    Après la version Linq est quand même plus concise, lisible et efficace, même si j'aurais eu instinctivement tendance à l'écrire comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    s.All(AddressOf Char.IsLetter) AndAlso s.Distinct.Count = s.Length
    Afin de pouvoir court-circuiter le test au premier caractère non valide (mais je chipote là )

    Cordialement !
    Nous sommes tous plus ou moins geek : ce qui est inutile nous est parfaitement indispensable ( © Celira )
    À quelle heure dormez-vous ?
    Censément, quelqu'un de sensé est censé s'exprimer sensément.

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    667
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 667
    Points : 1 164
    Points
    1 164
    Par défaut
    Bonjour,

    autrement une solution basique qui donne un message d'erreur si la chaine est incorrecte.

    1) contrôle si la chaine n'est composée que de lettres majuscules.
    2) Compte le nombre d'occurences qui ne doit pas dépasser 1.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
            Dim s As String = tbxEntree.Text
            If Regex.IsMatch(s, "^[A-Z]+$") Then
                For Each chr As Char In s
                    If Regex.Matches(s, chr).Count > 1 Then
                        MessageBox.Show("La chaine comprend déjà au moins deux " & chr & " , donc incorrecte.")
                        Exit For
                    End If
                Next
            Else
                MessageBox.Show("La chaine n'est pas composée que de MAJUSCULES, donc incorrecte.")
            End If
    Enfin pour Linq (plus esthétique) et les majuscules :

  8. #8
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 564
    Détails du profil
    Informations personnelles :
    Âge : 64

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 564
    Points : 4 441
    Points
    4 441
    Par défaut regex et lettres contigues recurrentes
    bonjour narutobaka
    Si c'est des lettres recurrentes "contigues" Regex permet en utilisant un nom de groupe pour l'expression (il faut nommer l'expression pattern regex) de compter les "recurrences de lettres" alphabetiques avec ce que MSDN DOC appelle les backrefrences
    La contiguite des caracteres recurrents est indispensable,autrement ils ne sont pas "vus".
    code exemple:
    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
     
    Imports System
    Imports System.Text.RegularExpressions
    Public Class frmRegexCompteCars
     
        Private Sub btnOccurencesCars_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOccurencesCars.Click
            'Define a regular expression for repeated chars.
            'groupe d'expression : [a-zA-Z]  caractere alphabetique 
            'syntaxe du nom groupe d'expression : ?'groupeNom'
            'suivie de: \k'groupeNom'
            Dim rx As New Regex("(?'groupeNom'[a-zA-Z])\'groupeNom'", _
                     RegexOptions.Compiled Or RegexOptions.IgnoreCase)
            ' Define a test string.
            Dim monText As String = "ABbCDEFFGhH"
            ' Find matches.
            Dim matches As MatchCollection = rx.Matches(monText)
     
            ' Report the number of matches found.
            Me.TextBox1.Text = Me.TextBox1.Text & "matches found in:" & matches.Count & vbCrLf
            Me.TextBox1.Text = Me.TextBox1.Text & monText & vbCrLf
            ' Report on each match.
            For Each match As Match In matches
                Dim groups As GroupCollection = match.Groups
                Me.TextBox1.Text = Me.TextBox1.Text & groups.Item("groupeNom").Value & _
                " repete en position : " & groups.Item(0).Index.ToString & vbCrLf
            Next
        End Sub
    End Class
    bon code......

Discussions similaires

  1. [WD18] Metre une colonne d'une Table sur une ligne d'une autre Table
    Par Totophe2 dans le forum WinDev
    Réponses: 2
    Dernier message: 22/11/2013, 12h58
  2. Réponses: 3
    Dernier message: 19/06/2007, 22h34
  3. Comment faire un rollover sur une image
    Par mackean dans le forum Balisage (X)HTML et validation W3C
    Réponses: 3
    Dernier message: 29/03/2007, 16h15
  4. Comment faire un explode sur une chaine comme suit ?
    Par sebnutt dans le forum Langage
    Réponses: 3
    Dernier message: 07/06/2006, 11h59
  5. comment faire un DROP sur une NESTED TABLE
    Par gilux dans le forum Oracle
    Réponses: 1
    Dernier message: 14/03/2006, 18h07

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