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 :

[RegEx] split en fonction des espace en excluant les portion entre quotes


Sujet :

Collection et Stream Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Invité
    Invité(e)
    Par défaut [RegEx] split en fonction des espace en excluant les portion entre quotes
    Bonjour,

    Je suis completement dans les choux pour concevoir une expression régulière.

    Je souhaite diviser une chaine avec "split" en utilisant les espaces commes séparateurs, mais en ignorant les portions de textes entre guillemets ( " ).

    Par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    String maChaine "aaaa bbbb \"cc cc\" dddd"
    maChaine.split(MonExpressionReguliere)
    Chaine d'origine :
    Décomposition souhaitée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    aaaa
    bbbb
    "cc cc"
    dddd

    Si vous pouviez m'aider à créer mon expression régulière car je me noi totalement dans les tutoriel à ce sujet.

    Merci d'avance !

  2. #2
    Membre éclairé Avatar de Appus
    Homme Profil pro
    Développeur multimédia
    Inscrit en
    Juin 2009
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur multimédia

    Informations forums :
    Inscription : Juin 2009
    Messages : 45
    Par défaut
    Bonjour,
    Voilà un très bon tuto :
    http://cyberzoide.developpez.com/java/regex/
    Un de plus, mais un des meilleurs !
    Je repasserai plus tard si j'ai une regex qui tient la route!

  3. #3
    Invité
    Invité(e)
    Par défaut
    Merci ! Je vais potasser tout ça.
    Dernière modification par mlny84 ; 26/06/2009 à 16h09. Motif: SMS

  4. #4
    Invité
    Invité(e)
    Par défaut
    Sa fait mal au crane ce tutoriel
    Je pense qu'il faudrait faire un truc avec les histoires de négation d'expression régulière, mais je n'arrive pas à voir comment

  5. #5
    Membre éclairé Avatar de Appus
    Homme Profil pro
    Développeur multimédia
    Inscrit en
    Juin 2009
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur multimédia

    Informations forums :
    Inscription : Juin 2009
    Messages : 45
    Par défaut
    Désolé mais je ne vois pas comment faire par le split...
    A moins de tout découper puis de recoller les morceaux dès qu'on détecte un guillemet...

    Sinon voici une proposition : Je suis sur qu'il y a plus simple:

    Code java : 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
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    package monPackage;
     
    import java.util.ArrayList;
    import java.util.regex.*;
     
    public class RegexSpaceSplit {
        public static void main(String[] args) {
            ArrayList<String> monDecoupage = new ArrayList<String>();
     
            // essai cas 0
            monDecoupage = decoupe("  \t \n \t");
            System.out.println("Cas 0");
            for (String sousChaine : monDecoupage) {
                System.out.println(sousChaine);
            }
     
            // essai cas 1
            monDecoupage = decoupe("   \" aaaa bbbb\" \" cc cc\" dd \"\"ee\n\tff \"gg\"\"hh\" ii ");
            System.out.println("\nCas 1");
            for (String sousChaine : monDecoupage) {
                System.out.println(sousChaine);
            }
     
            // essai cas 2
            monDecoupage = decoupe("aa bb bb \"cc cc\" dd\tdd \"eee\" f g \"hh\" \"ii\"\"jj\" kk");
            System.out.println("\nCas 2");
            for (String sousChaine : monDecoupage) {
                System.out.println(sousChaine);
            }
        }
     
        /**
         * c'est ici que tout est controle
         */
        public static ArrayList<String> decoupe(String chaineADecouper) {
            String regexChaineAvecGuillemets = "([\"]{1}[\\S\\s&&[^(\")]]*[\"]{1})";
            ArrayList<String> chainesSansGuillemets = getChainesSansGuillemets(
                    chaineADecouper, regexChaineAvecGuillemets);
            ArrayList<String> chainesAvecGuillemets = getChainesAvecGuillemets(
                    chaineADecouper, regexChaineAvecGuillemets);
            ArrayList<String> chaineDecoupee = new ArrayList<String>();
     
            // Cas 0
            // La chaine est vide
            if (chaineADecouper.trim().length() == 0)
                return chaineDecoupee;
     
            // Cas 1
            // La premiere chaine comporte de guillemets
            else if (chaineADecouper.trim().charAt(0) == '\"') {
                chainesSansGuillemets.remove(0);
                while ((chainesAvecGuillemets.size() > 0)
                        && (chainesSansGuillemets.size() > 0)) {
                    chaineDecoupee.add(chainesAvecGuillemets.remove(0));
                    for (String s : splitSpace(chainesSansGuillemets.remove(0)))
                        chaineDecoupee.add(s);
                }
            }
     
            // Cas 2
            // La premiere chaine NE comporte PAS de guillemets
            else {
                while ((chainesAvecGuillemets.size() > 0)
                        && (chainesSansGuillemets.size() > 0)) {
                    for (String s : splitSpace(chainesSansGuillemets.remove(0)))
                        chaineDecoupee.add(s);
                    chaineDecoupee.add(chainesAvecGuillemets.remove(0));
                }
            }
     
            // On ajoute les données restantes
            for (String s : chainesAvecGuillemets)
                chaineDecoupee.add(s);
            for (String s : chainesSansGuillemets)
                for (String s2 : splitSpace(s))
                    chaineDecoupee.add(s2);
            return chaineDecoupee;
        }
     
        /**
         * Renvoie toutes les chaines avec guillements
         */
        private static ArrayList<String> getChainesAvecGuillemets(String chaineADecouper, String regexChaineAvecGuillemets) {
            Pattern pattern = Pattern.compile(regexChaineAvecGuillemets);
     
            // création d’un moteur de recherche
            Matcher match = pattern.matcher(chaineADecouper);
            ArrayList<String> chainesRetour = new ArrayList<String>();
            while (match.find())
                for (int i = 0; i < match.groupCount(); i++)
                    chainesRetour.add(match.group(i));
            return chainesRetour;
        }
     
        /**
         * On decoupe des qu'on trouve une chaine avec des guillements aaaa bbbb
         * \"cc cc\" dd => (aaaa bbbb) et (dd)
         */
        private static ArrayList<String> getChainesSansGuillemets(String chaineADecouper, String regexChaineAvecGuillemets) {
            ArrayList<String> chainesRetour = new ArrayList<String>();
            String[] sousChaines = chaineADecouper.split(regexChaineAvecGuillemets);
            for (int i = 0; i < sousChaines.length; i++)
                chainesRetour.add(sousChaines[i]);
            return chainesRetour;
        }
     
        /**
         * split + trim mais retourne un ArrayList 
         */
        private static ArrayList<String> splitSpace(String chaine) {
            ArrayList<String> noBlank = new ArrayList<String>();
            String[] chaines = chaine.trim().split("\\s");
            for (int j = 0; j < chaines.length; j++)
                if (chaines[j].trim().length() > 0)
                    noBlank.add(chaines[j]);
            return noBlank;
        }
    }

    Je suis sur qu'il y a plus simple, je te laisserai chercher . En attendant, la solution que je te propose permet de retourner une ArrayList de String avec les différents éléments DANS L'ORDRE!!!! c'est ce "dans l'ordre" qui fait que ma proposition est aussi longue!

    Voilà l'expression régulière qui m'a permis de détecter un texte entre guillements :
    ([\"]{1}[\\S\\s&&[^(\")]]*[\"]{1})
    Elle vient de moi, donc pareil : il y a peut être plus simple!
    En espérant que ça te convienne?

  6. #6
    Invité
    Invité(e)
    Par défaut
    Wow. T'a du passer l'aprem pour concocter tout ça !!!
    Merci !

    De mon coté j'avais imaginé une autre solution qui est un peu "bidouille" mais qui donnera du code plus court que le tiens je pense :

    1/ Je recherche avec une expression régulière les portions de code entre guillemets
    2/ Je les remplace par du une chaine unique et improbable mais qui ne contient pas d'espaces
    3/ Je fait mon split(" ") sur les espaces
    4/ Je re-remplace mes chaines par leurs valeurs initiales.

    Dans l'exemple, sa donnerai :

    Chaine initiale :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    aaaa bbbb "cc cc" dddd "ee ee" ffff
    Chaine préparée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    aaaa bbbb $improbable$_1 dddd $improbable$_2 ffff
    avec $improbable$_1 <=> "cc cc" et $improbable$_2 <=> "ee ee"

    Après Split(" ")
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    aaaa
    bbbb
    $improbable$_1 
    dddd
    $improbable$_2
    ffff
    Chaine finale
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    aaaa
    bbbb
    "cc cc"
    dddd
    "ee ee"
    ffff

  7. #7
    Invité
    Invité(e)
    Par défaut
    Encore plus simple :

    Je parcours ma chaine espace par espace et je construit mon résultat mot par mot. Lorsque je tombe sur le caractère guillemet, j'avance directement jusqu'au prochain guillemet.

    Bon avec nos trois solution plus ou moins "bidouille" j'indique que le problème est "résolu", mais si quelqu'un à une "belle" solution avec l'expression régulière-parfaite-qui-fait-tout-d'un-coup, je suis preneur quand même !
    Dernière modification par mlny84 ; 27/06/2009 à 10h58. Motif: SMS

  8. #8
    Membre éclairé Avatar de Appus
    Homme Profil pro
    Développeur multimédia
    Inscrit en
    Juin 2009
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur multimédia

    Informations forums :
    Inscription : Juin 2009
    Messages : 45
    Par défaut
    J'ai mis un peu plus d'une heure.
    Pas mal comme idée, mais attention au cas particuliers car improbable n'est pas impossible!
    Sachant que tu as l'expression régulière qui permet de détecter les parties entre guillemets :
    ([\"]{1}[\\S\\s&&[^(\")]]*[\"]{1})
    Et même une méthode qui te permet de récupérer la liste des expressions entre guillemets, tu as toute les cartes en mains pour mettre en place ton idée!
    A toi de jouer!
    Sinon Ctrl+C, Ctrl+V et amélioration de ce que j'ai pondu. J'ai pas mis de copyright!!

Discussions similaires

  1. Champ Date comprenant des espaces : peut-on les supprimer?
    Par benhsaien dans le forum QlikView
    Réponses: 21
    Dernier message: 25/04/2012, 13h29
  2. Réponses: 18
    Dernier message: 29/04/2010, 16h40
  3. [regex] "Refus" des espaces
    Par alband85 dans le forum ASP.NET
    Réponses: 2
    Dernier message: 30/07/2007, 10h26
  4. Réponses: 2
    Dernier message: 17/05/2006, 11h43

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