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

C# Discussion :

Générateur d'une séquence avec expression régulières


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2012
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2012
    Messages : 59
    Par défaut Générateur d'une séquence avec expression régulières
    Bonjour à tous

    j'aimerai pouvoir programmer un bout de code qui me permettrait de générer une (des) séquence(s) de nombres...cette (ces) séquence(s) pourrait être définis dans le "style" des expressions régulières...
    de matière light bien sur...
    On donnerait l'expression pour la génération de la séquence et la taille de la séquence.
    dans le style
    genere("(12){3}",3) donnerait -> 12 12 12
    genere("(12){3}",2) donnerait -> 12 12

    genere("(12)+",5) donnerait -> 12 12 12 12 12 12

    genere("(12){3}(5)+",7) donnerait -> 12 12 12 5 5 5 5

    on pourrait préciser (avec les expressions) le début de la séquence...la fin et bien évidemment le milieu

    ainsi on pourrait écrire une expression du "style" ^((12){2})5+$(33)

    genere("^((12){2})5+$(33)",7) donnerait -> 12 12 5 5 5 5 33
    genere("^((12){2})5+$(33)",10) donnerait -> 12 12 5 5 5 5 5 5 5 33

    etc...

    Je n'ai pas d'idées sur le "comment" le développer... les expressions régulières sont ici des exemples... et pas réellement définies pour l'instant...
    il faudrait voir ce qui serait le mieux... si quelqu'un a une idée de spécification...

    Pensez-vous qu'il y aurait déjà un code qui reprendrait ce principe, ou s'y approcherait ?
    Si non comment quelqu'un aurait-il une idée ?

    Merci d'avance

    Fred

  2. #2
    Modérateur
    Avatar de DotNetMatt
    Homme Profil pro
    CTO
    Inscrit en
    Février 2010
    Messages
    3 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : CTO
    Secteur : Finance

    Informations forums :
    Inscription : Février 2010
    Messages : 3 611
    Billets dans le blog
    3
    Par défaut
    Pas simple à première vue ! En tout cas je pense que ce thread pourra t'aiguiller : http://stackoverflow.com/questions/3...-regex-pattern

    Tu trouveras sur ce thread une série d'articles qui parlent de ceci plus en détails : http://stackoverflow.com/questions/4...ion-in-c-sharp (dans la première réponse)

    Je ne sais pas si ça t'aidera, mais ça a l'air de correspondre à ce que tu cherhces à faire
    Less Is More
    Pensez à utiliser les boutons , et les balises code
    Desole pour l'absence d'accents, clavier US oblige
    Celui qui pense qu'un professionnel coute cher n'a aucune idee de ce que peut lui couter un incompetent.

  3. #3
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2012
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2012
    Messages : 59
    Par défaut
    Citation Envoyé par Matt07 Voir le message
    Pas simple à première vue ! En tout cas je pense que ce thread pourra t'aiguiller : http://stackoverflow.com/questions/3...-regex-pattern
    Merci...oui apparemment ça renvoie sur
    Xeger:
    "Think of it as the opposite of regular expression matchers. This library allows you to generate text that is guaranteed to match a regular expression passed in"

    Citation Envoyé par Matt07 Voir le message
    Tu trouveras sur ce thread une série d'articles qui parlent de ceci plus en détails : http://stackoverflow.com/questions/4...ion-in-c-sharp (dans la première réponse)

    Je ne sais pas si ça t'aidera, mais ça a l'air de correspondre à ce que tu cherhces à faire
    ...là désolé mais je n'ai pas trouvé ce que tu voulais me dire...la première réponse ?

    Je vais regarder déjà Xeger... même si le java je ne raffole pas... ça me donnera peut être une piste en tout cas...
    si tu as d'autres idées je suis preneur
    merci d'avance

    Petite précision... il est évident que je ne cherche pas à gérer tous les cas possibles comme dans la syntaxe des expressions régulières...
    juste les opérateurs:
    -commençant par
    -se terminant par

    les parenthèses de groupement
    le quantificateur +
    le quantificateur borné {n}

    Il me semble que cela suffit pour générer une suite


    Fred

  4. #4
    Modérateur
    Avatar de DotNetMatt
    Homme Profil pro
    CTO
    Inscrit en
    Février 2010
    Messages
    3 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : CTO
    Secteur : Finance

    Informations forums :
    Inscription : Février 2010
    Messages : 3 611
    Billets dans le blog
    3
    Par défaut
    Ce n'était peut-être pas très clair en effet Regarde la réponse de Leniel Macaferi, qui commence par "Take a look at my series of posts about this subject:".

    Ensuite il donne une série de liens qui renvoie vers une implémentation en C#.
    Less Is More
    Pensez à utiliser les boutons , et les balises code
    Desole pour l'absence d'accents, clavier US oblige
    Celui qui pense qu'un professionnel coute cher n'a aucune idee de ce que peut lui couter un incompetent.

  5. #5
    Membre Expert Avatar de meziantou
    Homme Profil pro
    autre
    Inscrit en
    Avril 2010
    Messages
    1 223
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : autre
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2010
    Messages : 1 223
    Par défaut
    Tu peux utiliser un outil de microsoft : Rex

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
                string regex = @"^([0-9]{1,5})$";
                RexSettings settings = new RexSettings(regex) { k = 10, encoding = CharacterEncoding.ASCII };
                var results = RexEngine.GenerateMembers(settings);
     
                foreach (var result in results)
                {
                    Console.WriteLine(result);
                }
    Il faut compiler ton programme en x86 pour que ca fonctionne.

  6. #6
    Membre émérite

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2011
    Messages
    487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2011
    Messages : 487
    Par défaut
    Je pense pas que ça soit si compliqué que ça si tu veux gérer que des cas assez "basiques".

    Déjà je te conseille de partir en TDD, vu que tu as déjà pas mal de usecases, ça permettra d'avoir une non reg constante pour un coût assez faible.

    Ensuite, est ce que tu pourrais écrire une spec plus clair que des usecases histoire que l'on comprenne à quoi sert chaque "opérateur" ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    genere("(12){3}",3) donnerait -> 12 12 12
    genere("(12){3}",2) donnerait -> 12 12
    Je vois pas bien l'utilité du {3} la en fait
    Mon blog sur les technos .NET et Agile -> http://blog.developpez.com/maximepalmisano/

  7. #7
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2012
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2012
    Messages : 59
    Par défaut
    Citation Envoyé par MaximePalmisano Voir le message

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    genere("(12){3}",3) donnerait -> 12 12 12
    genere("(12){3}",2) donnerait -> 12 12
    Je vois pas bien l'utilité du {3} la en fait
    Pour essayer de faire simple... on va dire qu'il serait possible de générer plusieurs suite de nombres...

    l'expression pourrait être la même mais la longueur (taille ?) augmenterait

    exemple 1
    pour (12){3} (sachant qu'implicitement la séquence aura une taille max de 3 ici)

    pour
    taille 1 -> 12
    taille 2 -> 12 12
    taille 3 -> 12 12 12
    taille 4 -> 12 12 12 ici on a pas de 4ème nombre bien évidement

    exemple 2
    si on a 12+... la séquence est infinie bien sur mais on on ne lui demande pas d'afficher une séquence infinie... la série sera une suite de 12...

    exemple 3
    (12 13 14)+ (la syntaxe est ici à "l'essai" car non totalement défini... c'est pour l'exemple)

    taille 1 -> 12
    taille 2 -> 12 13
    taille 3 -> 12 13 14
    taille 4 -> 12 13 14 12
    taille 5 -> etc à l'infini....

    Fred

  8. #8
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2012
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2012
    Messages : 59
    Par défaut
    Citation Envoyé par MaximePalmisano Voir le message
    Je pense pas que ça soit si compliqué que ça si tu veux gérer que des cas assez "basiques".

    Déjà je te conseille de partir en TDD, vu que tu as déjà pas mal de usecases, ça permettra d'avoir une non reg constante pour un coût assez faible.
    Je viens de lire un article sur la TDD :
    http://despeludo.developpez.com/arti...estsunitaires/
    bon ben ok... pas sur que ça m'aide

    Citation Envoyé par MaximePalmisano Voir le message
    Ensuite, est ce que tu pourrais écrire une spec plus clair que des usecases histoire que l'on comprenne à quoi sert chaque "opérateur" ?
    ok pour une spécif plus précise... c'est un premier jet

    *nombres constitué de chiffres acceptés pour les valeurs

    *les caractères espace ou virgule sont acceptés pour séparer chaque valeurs de la série

    *l'expression régulière devra obligatoirement commencer par un "^"
    et se terminer par un "$"

    *les parenthèses "(" et ")" englobe un groupe d'une ou plusieurs valeurs ou d'autres groupes de valeurs
    ex: (12) ou (12 13) ou ((12 13) (14 15)) (ce dernier cas ne sert pas à grand chose ici mais avec le "+" ou "{n}" associé si)

    *le "+" (de 1 à n répétition) s'applique sur une valeur
    ou un groupe de valeurs si il y a une parenthèse englobant ce groupe
    ex:
    12+ répétition du 12
    (12 13 )+ répétition de la séquence 12 13...

    *le {n} s'applique sur une valeur
    ou un groupe de valeurs si il y a une parenthèse englobant ce groupe
    ex:
    12{3} répétition du "12" 3 fois
    (12 13){5} répétition de la séquence "12 13" 5 fois

    on peux demander n'importe quel taille de séquence à générer... mais si l'expression ne le permet pas on n'ajoute rien

    ex: ^12$
    séquence de longueur 1 donnera -> 12
    séquence de longueur 2 donnera -> 12
    séquence de longueur 3 donnera -> 12

    par contre ^(12 )+$ (il y a un espace c'est voulu)
    séquence de longueur 1 donnera -> 12
    séquence de longueur 2 donnera -> 12 12
    séquence de longueur 3 donnera -> 12 12 12
    etc

    Fred

  9. #9
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2012
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2012
    Messages : 59
    Par défaut
    Citation Envoyé par meziantou Voir le message
    Tu peux utiliser un outil de microsoft : Rex

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
                string regex = @"^([0-9]{1,5})$";
                RexSettings settings = new RexSettings(regex) { k = 10, encoding = CharacterEncoding.ASCII };
                var results = RexEngine.GenerateMembers(settings);
     
                foreach (var result in results)
                {
                    Console.WriteLine(result);
                }
    Il faut compiler ton programme en x86 pour que ca fonctionne.
    j'ai bien été sur le lien... c'est un outil en version web... et au download on récupère un outil en ligne de commande... je ne vois pas de source ici

    Fred

  10. #10
    Membre Expert Avatar de meziantou
    Homme Profil pro
    autre
    Inscrit en
    Avril 2010
    Messages
    1 223
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : autre
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2010
    Messages : 1 223
    Par défaut
    Citation Envoyé par deuzef68 Voir le message
    j'ai bien été sur le lien... c'est un outil en version web... et au download on récupère un outil en ligne de commande... je ne vois pas de source ici

    Fred
    En effet il n'y a pas de source. Tu peux tout de même ajouter l'exécutable en référence de ton projet et utiliser le code que j'ai indiqué précédemment.

  11. #11
    Membre émérite

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2011
    Messages
    487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2011
    Messages : 487
    Par défaut
    Bon, ça m'a turlupiné alors j'ai essayé de le faire rapidos, voici ce que ça donne:


    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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
     
    private const string SEPARATOR = " ";
    		private const string INFINITE_MULTIPLIER = "+";
    		private const string PATTERN = @"\(([0-9]+)\)" + @"(\{[0-9]+\}|\+|)";
     
    		public string Generate(string numberRegex, int maxLength)
    		{
    			if(numberRegex == null)
    				throw new ArgumentNullException();
     
    			if(numberRegex == string.Empty)
    				throw new ArgumentException();
     
    			if(maxLength <= 0)
    				throw new ArgumentOutOfRangeException();
     
    			return Parse(numberRegex, maxLength)
    				.Aggregate((s1, s2) => s1 + SEPARATOR + s2);
    		}
     
    		private IEnumerable<string> Parse(string numberRegex, int maxLength)
    		{
    			List<string> result = new List<string>();
    			MatchCollection matches = Regex.Matches(numberRegex, PATTERN);
     
    			if(matches.Count == 0)
    				throw new ArgumentException();
     
    			foreach(Match match in matches)
    			{
    				if(match.Groups.Count < 2)
    					throw new ArgumentException();
     
    				string number = match.Groups[1].Value;
    				string multiplierString = match.Groups[2].Value;
     
    				int multiplier = GetMultiplier(multiplierString, maxLength);
     
    				for(int i = 0; i < multiplier; i++)
    					result.Add(number);
    			}
     
    			return result.Take(maxLength);
    		}
     
    		public string GetFirstNumberFrom(string s)
    		{
    			Match match = Regex.Match(s, "^[0-9]+");
     
    			if(!match.Success)
    				throw new ArgumentException();
     
    			return match.Value;
    		}
     
    		public int GetMultiplier(string s, int maxLength)
    		{
    			if(s.Length == 0)
    				return 1;
     
    			if(s.EndsWith(INFINITE_MULTIPLIER))
    				return maxLength;
     
    			string multiplier = Regex.Match(s, "[0-9]+").Value;
    			return int.Parse(multiplier);
    		}
    Et les tests:

    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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
     
    private NumberRegex regex;
     
    		[TestInitialize]
    		public void Init()
    		{
    			regex = new NumberRegex();
    		}
     
    		[TestMethod]
    		public void Generate_12_3_3()
    		{
    			string output = regex.Generate("(12){3}", 3);
    			Assert.AreEqual("12 12 12", output);
    		}
     
    		[TestMethod]
    		public void Generate_12_3_2()
    		{
    			string output = regex.Generate("(12){3}", 2);
    			Assert.AreEqual("12 12", output);
    		}
     
    		[TestMethod]
    		public void Generate_12_Plus_2()
    		{
    			string output = regex.Generate("(12)+", 2);
    			Assert.AreEqual("12 12", output);
    		}
     
    		[TestMethod]
    		public void Generate_12_Plus_5()
    		{
    			string output = regex.Generate("(12)+", 5);
    			Assert.AreEqual("12 12 12 12 12", output);
    		}
     
    		[TestMethod]
    		public void Generate_12_Plus_4_5_Ignore()
    		{
    			string output = regex.Generate("(12)+(4)", 5);
    			Assert.AreEqual("12 12 12 12 12", output);
    		}
     
    		[TestMethod]
    		public void Generate_12()
    		{
    			string output = regex.Generate("(12)", 5);
    			Assert.AreEqual("12", output);
    		}
     
    		#region Exception cases
     
    		[TestMethod]
    		[ExpectedException(typeof(ArgumentOutOfRangeException))]
    		public void Generate_MaxLength_Negative()
    		{
    			regex.Generate("12", -2);
    		}
     
    		[TestMethod]
    		[ExpectedException(typeof(ArgumentOutOfRangeException))]
    		public void Generate_MaxLength_Zero()
    		{
    			regex.Generate("12", 0);
    		}
     
    		[TestMethod]
    		[ExpectedException(typeof(ArgumentException))]
    		public void Generate_StringEmpty()
    		{
    			regex.Generate("", 5);
    		}
     
    		[TestMethod]
    		[ExpectedException(typeof(ArgumentNullException))]
    		public void Generate_StringNull()
    		{
    			regex.Generate(null, 5);
    		}
     
    		#endregion
    C'est pas super bien écrit et les cas sont loin d'être tous gérés mais ça te donne une base pour commencer à voir ce que tu veux faire réellement. Bon courage
    Mon blog sur les technos .NET et Agile -> http://blog.developpez.com/maximepalmisano/

  12. #12
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2012
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2012
    Messages : 59
    Par défaut
    Citation Envoyé par MaximePalmisano Voir le message
    Bon, ça m'a turlupiné alors j'ai essayé de le faire rapidos, voici ce que ça donne:

    C'est pas super bien écrit et les cas sont loin d'être tous gérés mais ça te donne une base pour commencer à voir ce que tu veux faire réellement. Bon courage
    Merci c'est sympa... je vais regarder tout ça dès que j'aurais un moment pour l'intégrer.

    Encore merci.

    Question subsidiaire: ayant ressorti ma doc lex/yacc il me semble (sauf si on me dit le contraire) qu'on doit pouvoir aussi le réaliser en lex/yacc.
    Il y a t'il un lex/yacc pour c# ?

    Fred

Discussions similaires

  1. Réponses: 6
    Dernier message: 30/01/2008, 22h20
  2. [RegEx] Extraction d'une partie d'une URL par expression régulière
    Par Maxbenji dans le forum Langage
    Réponses: 2
    Dernier message: 16/01/2007, 22h26
  3. [RegEx] Contrôle avec expression régulière
    Par lodan dans le forum Langage
    Réponses: 8
    Dernier message: 23/10/2006, 19h32
  4. [RegEx] Problème avec expressions régulières.
    Par Cygnus Saint dans le forum Langage
    Réponses: 12
    Dernier message: 14/08/2006, 11h55
  5. [C#] Caractères hexadécimal avec expressions régulières
    Par shinchan dans le forum Windows Forms
    Réponses: 4
    Dernier message: 16/01/2006, 11h41

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