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

Collection et Stream Java Discussion :

Rédaction d'une expression régulière


Sujet :

Collection et Stream Java

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    247
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 247
    Points : 78
    Points
    78
    Par défaut Rédaction d'une expression régulière
    Bonjour, pour la première fois je dois rédiger une expression régulière.
    J'ai regardé quelques cours en ligne mais je dois avouer que cela me semble bien compliqué alors que mon expression est très simple à expliquer.
    J'aimerais que mon expression coupe une chaine de la façon suivante:

    delimiteur suivi de n'importe quoi suivi de delimiteur et separateur ou separateur

    delimiteur et separateur sont des caracteres que je definis dynamiquement
    je la redigerais de la façon suivante
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (delimiteur .* delimiteur separateur)|separateur
    ce la n'a pas l'air correct malheuresement.

    Merci de me venir en aide

  2. #2
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,


    Sans le code exact ca va être difficile de t'aider...


    a++

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    247
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 247
    Points : 78
    Points
    78
    Par défaut
    par exemple avec un delimiteur ayant pour valeur " et un separateur ayant pour valeur ;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    String maChaine="ceci;est;un;test"
    String[] result=chaine.split(maRegEx)
    devrait me retourner un tableau de 4 valeurs (ceci, est, un, test). Je viens de tester, cela fonctionne

    Par contre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    String maChaine="\"ceci\";est;un;test"
    devrait retourner un tableau avec les valeurs suivantes:"ceci", est, un test.
    Mais cela ne fonctionne pas: la première valeur("ceci") n'est pas retenue

    PS: j'ai modifié ma regex de la manière suivante et ça a l'air de fonctionner.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (delimiteur.^delimiteur* delimiteur separateur)|separateur
    Je suis toujours preneur de vos avis !

  4. #4
    Membre confirmé
    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2010
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 39
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Octobre 2010
    Messages : 158
    Points : 556
    Points
    556
    Par défaut
    Citation Envoyé par enzostar Voir le message
    J'aimerais que mon expression coupe une chaine de la façon suivante:
    delimiteur suivi de n'importe quoi suivi de delimiteur et separateur ou separateur
    Citation Envoyé par enzostar Voir le message
    par exemple avec un delimiteur ayant pour valeur " et un separateur ayant pour valeur ;
    [...]
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    String maChaine="\"ceci\";est;un;test"
    devrait retourner un tableau avec les valeurs suivantes:"ceci", est, un test.
    Mais cela ne fonctionne pas: la première valeur("ceci") n'est pas retenue
    Tu as donc utilisé l'expression comme expression régulière ?

    Réexplique ce que tu veux faire exactement, car ce comportement semble bien correspondre à ce que tu as décrit dans ton premier message : la chaîne "ceci"; correspond à la description " suivi de n'importe quoi suivi de " et ; et elle est donc considérée un délimiteur pour le split.

    Si tu veux que la chaîne "\"ceci\";est;un;test" soit splittée en quatre morceaux "\"ceci\"", "est", "un" et "test", c'est donc que tu veux seulement considérer le point-virgule comme délimiteur, non ?
    Bref, je ne comprends pas ce que tu cherches à faire.

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    247
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 247
    Points : 78
    Points
    78
    Par défaut
    c'est donc que tu veux seulement considérer le point-virgule comme délimiteur, non ?
    Bref, je ne comprends pas ce que tu cherches à faire.[/QUOTE]
    non car un ; entre deux delimiteurs ne doit pas être pris en compte.
    J'essaie d'être plus clair:
    j'aimerais que le debut de la regex soit mon delimiteur
    et que la fin soit delimiteur suivi de separateur
    entre le debut et la fin on peut trouver tous les caracteres (y compris separateur et delimiteur)
    D'ailleurs je viens de tester avec cette chaine:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    String chaine = "Je \"suis\" ;zen;";
    et ça split apres "suis" alors qu'il y a un espace entre le " et le ;

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    299
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2009
    Messages : 299
    Points : 422
    Points
    422
    Par défaut
    Bonjour,
    ne peux-tu tout simplement pas utiliser un séparateur que tu ne risques pas de retrouver dans tes phrases ? puis faire un simple split() ?
    Le séparateur peut-être composé de plusieurs caractères, il suffit de trouver une association improbable !
    Pour être caricatural, tu pourrais très bien faire ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    String chaine = ",;=:#MONSEP#\"Je suis stressé\";...#MONSEP#etc etc";
    String[] resultat = chaine.split("#MONSEP#");
     
    // -> [,;=:] ["Je suis stressé";...] [etc etc]
    Si tu n'as pas le choix du séparateur, donne nous une ligne contenant les différents problèmes que tu rencontres et le résultat que tu souhaiterais, car en séparant tes problèmes comme tu l'as fait dans les posts précédents, nous allons te trouver une solution pour chaque problème individuellement mais qui ne sera peut-être pas bonne globalement.

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    247
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 247
    Points : 78
    Points
    78
    Par défaut
    cette expression m'est utile pour traiter un fichier csv, donc pour le separateur, je n'ai pas le choix (c'est soit ',' soit ';')

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    299
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2009
    Messages : 299
    Points : 422
    Points
    422
    Par défaut
    Donne nous une ligne complète du fichier, contenant les différents soucis, ainsi que le résultat que tu souhaiterai

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    247
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 247
    Points : 78
    Points
    78
    Par défaut
    Citation Envoyé par Caalador Voir le message
    Donne nous une ligne complète du fichier, contenant les différents soucis, ainsi que le résultat que tu souhaiterai
    Voici une ligne:et j'aimerais comme resultat:

  10. #10
    Membre confirmé
    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2010
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 39
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Octobre 2010
    Messages : 158
    Points : 556
    Points
    556
    Par défaut
    Citation Envoyé par enzostar Voir le message
    J'essaie d'être plus clair [...]
    En fait là ce n'est pas vraiment plus clair car tu continues à expliquer ta regex au lieu d'expliquer ce que tu veux faire


    Citation Envoyé par enzostar Voir le message
    un ; entre deux delimiteurs ne doit pas être pris en compte.
    Citation Envoyé par enzostar Voir le message
    cette expression m'est utile pour traiter un fichier csv
    OK, donc tu veux "splitter" ta chaîne en considérant comme séparateur le caractère ; sauf lorsqu'il est encadré par deux ".

    Tu peux utiliser un lookaround dans ton expression régulière pour dire que le caractère ; ne doit pas être suivi ou précédé par " :

    • lookahead ";(?!\")" = un ; qui n'est pas suivi par "
    • lookbehind "(?<!\");" = un ; qui n'est pas précédé par "


    Du coup, l'expression régulière "(?<!\");|;(?!\")" peut te convenir :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    String regex = ";(?!\")|(?<!\");";
    String string = "\";toto\";;\"ti\";\"ti;tutu;;";
    String[] split = string.split(regex, -1);
     
    for (int i = 0 ; i < split.length ; i++)
    {
        System.out.println(">>>"+split[i]+"<<<");
    }
    affiche
    >>>"<<<
    >>>toto"<<<
    >>><<<
    >>>"ti";"ti<<<
    >>>tutu<<<
    >>><<<
    >>><<<

  11. #11
    Membre confirmé
    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2010
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 39
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Octobre 2010
    Messages : 158
    Points : 556
    Points
    556
    Par défaut
    Citation Envoyé par enzostar Voir le message
    Voici une ligne:et j'aimerais comme resultat:
    Ah, il faut aussi traiter les cas des valeurs comprises entre deux "...

    Est-ce que tu es obligé d'utiliser la méthode split ? Ou est-ce que tu veux juste obtenir ton tableau de valeurs quelle que soit la méthode employée ?
    Parce que le split n'est pas adapté à ce traitement, où il faut apparier les guillemets.

  12. #12
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    247
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 247
    Points : 78
    Points
    78
    Par défaut
    Citation Envoyé par SucreGlace Voir le message
    Est-ce que tu es obligé d'utiliser la méthode split ? Ou est-ce que tu veux juste obtenir ton tableau de valeurs quelle que soit la méthode employée ?
    Parce que le split n'est pas adapté à ce traitement, où il faut apparier les guillemets.
    J'aimerais trouver une expression reguliere adaptée pour l'utiliser dans un split.
    Pourquoi, tu aurais une autre idée ?

  13. #13
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    299
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2009
    Messages : 299
    Points : 422
    Points
    422
    Par défaut
    J'avoue que ton soucis m'a fait un peu tourner la tête.
    J'ai fait ça qui semble fonctionner, par contre je pense qu'il y a sûrement beaucoup mieux.
    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
    String chaine = "1;4;\"Je suis; \"\"zen\"\"\";";
    chaine = chaine.replaceAll(";\"", ";##");
    chaine = chaine.replaceAll("\";", "##;");
     
    String[] array = chaine.split(";#|#;");
    List<String> l = new ArrayList<String>();
     
    for(String s : array){
    	if(s.contains("#")){
    		s = s.replaceAll("#", "");
    		l.add(s);
    	}
    	else if(s.contains(";")){
    		String[] decoupe = s.split(";");
    		for(String s2 : decoupe){
    			l.add(s2);
    		}
    	}
    }
     
    System.out.println(l.toString());
    // -> [1, 4, Je suis; ""zen""]
    En espérant que ca t'aide.
    Le gros point faible évidemment, c'est que tes phrases ne doivent pas contenir de #. Si c'est le cas, une solution simple serait de rendre ce séparateur un peu plus complexe.

  14. #14
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    247
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 247
    Points : 78
    Points
    78
    Par défaut
    est-ce qu'on peut cumuler les lookbehind ?
    Je crois que cela solutionnerait mon problème puisque il me faut une expression reguliere qui traduise que le point-virgule de fin doit être précédé d'une guillemet elle meme ne doit pas être précédée d'une guillemet.
    qu'en penses-tu ?

  15. #15
    Membre confirmé
    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2010
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 39
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Octobre 2010
    Messages : 158
    Points : 556
    Points
    556
    Par défaut
    Citation Envoyé par enzostar Voir le message
    Pourquoi, tu aurais une autre idée ?
    Oui
    Dans le cas du CSV, où une valeur peut être encadrée ou non de guillemets, le split n'est pas adapté car les "séparateurs" ne sont pas indépendants les uns des autres.
    Je te propose d'identifier par une expression régulière non pas les séparateurs, mais plutôt les valeurs.

    Exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    String regex = "(^|(?<=;))([^\";])*((?=;)|$)|((?<=^\")|(?<=;\"))([^\"]|\"\")*((?=\";)|(?=\"$))";
    Pattern p = Pattern.compile(regex);
    Matcher m = p.matcher(";\"\";aaaaa;;bb\"bb;\"ccccc\";\"ddd;dd\";ee\"\"ee;\"ff\"\"ff\"");
    while (m.find())
    {
       System.out.println(">>>"+m.group()+"<<<");
    }
    affiche
    >>><<<
    >>><<<
    >>>aaaaa<<<
    >>><<<
    >>>ccccc<<<
    >>>ddd;dd<<<
    >>>ff""ff<<<

    Décomposition de la regex:

    Une valeur non encadrée par des délimiteurs doit:

    • soit être en début de chaîne, soit être précédée d'un séparateur: (^|(?<=; ))
    • être composée d'une suite de caractère qui ne sont ni le délimiteur ni le séparateur : ([^\";])*
    • soit être en fin de chaîne, soit être suivie d'un séparateur : ((?=; )|$)


    Une valeur encadrée par des délimiteurs doit:

    • soit être en début de chaîne et précédée d'un délimiteur, soit être précédée d'un séparateur et d'un délimiteur : ((?<=^\")|(?<=;\"))
    • être composée d'une suite de caractères qui peuvent être un double délimiteur ou un séparateur : ([^\"]|\"\")*
    • soit être en fin de chaîne et suivie d'un délimiteur, soit être suivie d'un délimiteur et d'un séparateur : ((?=\"; )|(?=\"$))



    [EDIT] grrrr, à chaque fois je mets un quart d'heure à rédiger mon message, et deux autres sont apparus entre temps

  16. #16
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    247
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 247
    Points : 78
    Points
    78
    Par défaut
    mes delimiteurs ne sont pas forcément des guillemets et mes separateurs pas forcéments des points-virgules. Ton expression reste-t-elle valable ?
    Tu prends le temps de repondre, c'est très appréciable ;-)

  17. #17
    Membre confirmé
    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2010
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 39
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Octobre 2010
    Messages : 158
    Points : 556
    Points
    556
    Par défaut
    Citation Envoyé par enzostar Voir le message
    est-ce qu'on peut cumuler les lookbehind ?
    Je crois que cela solutionnerait mon problème puisque il me faut une expression reguliere qui traduise que le point-virgule de fin doit être précédé d'une guillemet elle meme ne doit pas être précédée d'une guillemet.
    qu'en penses-tu ?
    Le point-virgule de fin doit être précédé d'un guillemet si le point-virgule précédent était suivi d'un guillemet. Les séparateurs ne sont pas vraiment indépendants les uns des autres, c'est pour ça que je pense qu'un split, basé sur la définition des séparateurs, est inadapté.

  18. #18
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    247
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 247
    Points : 78
    Points
    78
    Par défaut
    exact...

  19. #19
    Membre confirmé
    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2010
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 39
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Octobre 2010
    Messages : 158
    Points : 556
    Points
    556
    Par défaut
    Citation Envoyé par enzostar Voir le message
    mes delimiteurs ne sont pas forcément des guillemets et mes separateurs pas forcéments des points-virgules. Ton expression reste-t-elle valable ?
    Bien sûr.
    Fais juste attention s'il s'agit de caractères qui ont une signification spéciale dans les regex, il faudra alors les échapper pour que le moteur de regex les interprète corectement (exemple : tu ne peux pas insérer un pipe "|" directement dans la regex, il faut utiliser "\|" si tu veux que ça représente le caractère pipe). Si la regex est générée automatiquement dans ton code à partir des délimiteurs et séparateurs donnés par l'utilisateur, il faudra bien penser à traiter les cas spéciaux.

  20. #20
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    247
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 247
    Points : 78
    Points
    78
    Par défaut
    je remplace les ; par mon separateur et les \" par mon délimiteur ?
    Je pense que ta méthode ne me convient pas car j'ai besoin des guillemets et ton expression me les retire

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [EXP] Evaluation dans une expression régulière
    Par SergentHeinz dans le forum Langage
    Réponses: 7
    Dernier message: 10/11/2005, 18h17
  2. Une expression réguliére
    Par BRAUKRIS dans le forum PostgreSQL
    Réponses: 2
    Dernier message: 09/09/2005, 20h14
  3. Réponses: 6
    Dernier message: 17/08/2005, 12h38
  4. Problème sur une expression régulière
    Par Verbal-Quint dans le forum Langage
    Réponses: 6
    Dernier message: 12/11/2004, 10h54
  5. [Regex] Vérifier qu'une chaîne respecte une expression régulière
    Par PeteMitchell dans le forum Collection et Stream
    Réponses: 7
    Dernier message: 13/05/2004, 14h22

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