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

Java Discussion :

regex CSV avec des guillemets


Sujet :

Java

  1. #1
    Rédacteur
    Avatar de thierryler
    Homme Profil pro
    Inscrit en
    Octobre 2007
    Messages
    4 078
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 078
    Points : 12 815
    Points
    12 815
    Par défaut regex CSV avec des guillemets
    Bonjour,

    J'ai un fichier csv, avec mes valeurs séparées par des virgules. Quand les champs contiennent des virgules, ils sont encapsulés par des guillemets :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    # une ligne exemple
    "Maman","Papa","Julie, Franck et Tom","Mamy","Papy"
    Dans mon exemple la 3ème colonne, avec "Julie, Franck et Tom" contient le séparateur.

    Du coup, je ne sais pas trop comment faire mon regex pour le slit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    String line <== "Maman","Papa","Julie, Franck et Tom","Mamy","Papy"
     
    String regex = "???"
     
    String[] values = line.split(regex)
    Bon je suis trop mauvais en regex alors excusez moi par avance si c'est trop simple...
    Thierry Leriche-Dessirier
    Consultant Java JEE Web Agile freelance
    Rédacteur pour Developpez
    Professeur de Génie Logiciel à l'ESIEA

    Site : http://www.icauda.com / Linked'in : http://www.linkedin.com/in/thierryler / Twitter : @ThierryLeriche

  2. #2
    Membre chevronné
    Inscrit en
    Mai 2006
    Messages
    1 364
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 1 364
    Points : 1 984
    Points
    1 984
    Par défaut
    Salut,

    Pour le meme genre de probleme, je suis passé par un parse par programme. Parce qu'il ne faut pas oublier qu'un champ peut contenir un '\n' (et donc un getLine ne suffit pas)...

    Pour les regex, désolé mais c'est pas mon truc non plus

  3. #3
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : Août 2005
    Messages : 2 894
    Points : 7 083
    Points
    7 083
    Par défaut
    Je ne sais pas trop si c'est possible d'utiliser une expression régulière pour ça.

    J'ai plutôt l'habitude pour traiter ce genre de chaîne d'utiliser des "modes".
    Le principe dans ton cas :
    Je cherche le premier caractère spécial le guillemet ou la virgule.
    Si c'est un guillemet et que je suis en mode "Guillemet ouvert" (un petit booléen fait l'affaire), je passe en mode "guillemet fermé".
    Si c'est un guillemet et que je suis en mode "Guillemet fermé", je passe en mode "guillemet ouvert".
    Si c'est une virgule et que je suis en mode "Guillemet ouvert", j'ignore la virgule.
    Si c'est une virgule et que je suis en mode "Guillemet fermé", c'est la fin de la valeur.

    Il reste à vérifier quelques points:
    • L'ouverture d'un guillemet n'est valable qu'en début de valeur.
    • La fin du mode "Guillemet fermé" implique que le caractère suivant est une virgule.
    • Il faut traiter le cas où la valeur contient un saut de ligne
    • Il faut traiter le cas où la valeur contient un guillemet et un saut de ligne
    • Il faut traiter le cas où la valeur contient un guillemet et une virgule
    Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
    Ceylon : Installation - Concepts de base - Typage - Appels et arguments

    ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
    Une solution vous convient ? N'oubliez pas le tag
    Signature par pitipoisson

  4. #4
    Membre confirmé
    Inscrit en
    Mai 2007
    Messages
    335
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 335
    Points : 511
    Points
    511
    Par défaut
    Bonjour,
    pas si simple en fait, puisque la détection de virgule dépend du contexte, on est à la limite de la regexp et de l'analyse BNF non ?

    bref, plutôt qu'un split, je passerais par un Matcher en bouclant sur des find/group ,on matche un groupe et on traite sa valeur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     Pattern p = Pattern.compile("\"([^\"]*)\"([^,]*),");
     Matcher m = p.matcher("aaaaab");//la Ligne à matcher
    while(m.find){
      String s1 = m.group(1);//contient les chaines avec guillemets
      String s2 = m.group(2);//contient les chaines sans guillemets
      String s=s1;
      if(s1.length() == 0) s=s2
      ...traiter s...
    }
    il y a surement plus efficient comme regexp... mais ça devrais marcher.

    Edit: (petite modif sur la regexp.)
    oubli: il faudrait matcher la fin de ligne avec "\"([^\"]*)\"([^,]*)$" par exemple.

    Il y eu plein de réponse pendant que j'écrivais Donc pour la remarque du multi-ligne, c'est clair qu'une regexp ne peut pas être multi-ligne.

  5. #5
    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 : 38
    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
    J'avais déjà essayé de composer une regex utilisable sur du CSV.
    Je ne sais pas si ça te conviendra, mais tu peux toujours aller voir ce message.
    Une réponse vous a aidé ? Votez pour !
    Vous n'avez plus de problème ? N'oubliez pas de le signaler !

  6. #6
    Rédacteur
    Avatar de thierryler
    Homme Profil pro
    Inscrit en
    Octobre 2007
    Messages
    4 078
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 078
    Points : 12 815
    Points
    12 815
    Par défaut
    En fait, dans un premier temps, je voudrais juste des valeurs sur une seule ligne.

    Mais je peux avoir les séparateurs suivants :
    * virgule ou
    * point-virgule ou
    * barre ou
    * tab

    Par contre je n'utilise que les guillemets comme délimiteur.

    Dans un second temps, je vais avoir besoin de valeurs sur plusieurs lignes, donc je ne serai plus en mesure d'utiliser br.readLine()...
    Thierry Leriche-Dessirier
    Consultant Java JEE Web Agile freelance
    Rédacteur pour Developpez
    Professeur de Génie Logiciel à l'ESIEA

    Site : http://www.icauda.com / Linked'in : http://www.linkedin.com/in/thierryler / Twitter : @ThierryLeriche

  7. #7
    Membre chevronné
    Inscrit en
    Mai 2006
    Messages
    1 364
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 1 364
    Points : 1 984
    Points
    1 984
    Par défaut
    Cadeau
    Ca renvoie un tableau de String (chacune correspondant à une cellule)

    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
    83
    84
    85
    86
    87
    88
    89
          public static String[] splitNextLigneCsv(StreamReader srFichier)
          {
             String[] ret = null;
             List<String> listCells = new List<String>();
             System.Text.StringBuilder ligne = new System.Text.StringBuilder(1024);
     
             bool isOpen = false;
             int n = srFichier.Read();
             bool shouldContinue = true;
             while ((n != -1) &&
                (shouldContinue != false))
             {
                char c = (char)n;
                if (c == '"')
                {
                   if (ligne.Length == 0)
                   {
                      // C'est le premier guillement, on l'ignore
                      isOpen = true;
                      n = srFichier.Read();
                   }
                   else
                   {
                      // On lit le prochain caractere. Si c'est un ';'
                      // un retour chariot ou la fin du fichier, on l'ignore
                      n = srFichier.Read();
                      if (n != -1)
                      {
                         if (((char)n != ';') &&
                            ((char)n != '\n') &&
                            ((char)n != '\r'))
                         {
                            ligne.Append(c);
                         }
                         else
                         {
                            //Fin de la cellule
                            isOpen = false;
                         }
                      }
                      else
                      {
                         //Fin de la cellule et du fichier
                         listCells.Add(ligne.ToString());
                         ligne.Clear();
                         shouldContinue = false;
                      }
                   }
                }
                else if ((c == ';') ||
                   (c == '\r') ||
                   (c == '\n'))
                {
                   if (isOpen == false)
                   {
                      //Fin de la cellule
                      if (c == ';')
                      {
                         listCells.Add(ligne.ToString());
                         ligne.Clear();
                      }
                      else if (listCells.Count > 0)
                      {
                         listCells.Add(ligne.ToString());
                         ligne.Clear();
                         shouldContinue = false;
                      }
     
                   }
                   else
                   {
                      ligne.Append(c);
                   }
                   n = srFichier.Read();
                }
                else
                {
                   ligne.Append(c);
                   n = srFichier.Read();
                }
             }
     
             if (listCells.Count > 0)
             {
                ret = listCells.ToArray();
             }
     
             return ret;
          }

  8. #8
    Rédacteur
    Avatar de thierryler
    Homme Profil pro
    Inscrit en
    Octobre 2007
    Messages
    4 078
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 078
    Points : 12 815
    Points
    12 815
    Par défaut
    heu y a plein de classes inconnues...
    Thierry Leriche-Dessirier
    Consultant Java JEE Web Agile freelance
    Rédacteur pour Developpez
    Professeur de Génie Logiciel à l'ESIEA

    Site : http://www.icauda.com / Linked'in : http://www.linkedin.com/in/thierryler / Twitter : @ThierryLeriche

  9. #9
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : Août 2005
    Messages : 2 894
    Points : 7 083
    Points
    7 083
    Par défaut
    J'ai pas lu le code de hwoarang mais ca doit être l'idée, seulement il doit pas coder en Java mais en .NET

    La correspondance :
    • List => java.util.List
    • new List<String>() => new LinkedList<String>()
    • System.Text.StringBuilder => java.lang.StringBuilder
    • StreamReader => java.io.Reader
    Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
    Ceylon : Installation - Concepts de base - Typage - Appels et arguments

    ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
    Une solution vous convient ? N'oubliez pas le tag
    Signature par pitipoisson

  10. #10
    Membre confirmé
    Avatar de william44290
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Juin 2009
    Messages
    400
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France

    Informations professionnelles :
    Activité : Responsable de service informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 400
    Points : 575
    Points
    575
    Par défaut
    j'aurais fait comme cela :

    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
            String line = '"'+"Maman"+'"'+","+'"'+"Papa"+'"'+","+'"'+"Julie, Franck et Tom"+'"'+","+'"'+"Mamy"+'"'+","+'"'+"Papy"+'"';
            String passOne=line.substring(1,line.length()-1);
            String regex = '"'+","+'"';
            String[] passTo = passOne.split(regex);
     
            // Vérification
            System.out.println("!"+line+"!");
     
            System.out.println("En deux passe");
            for (int i=0;i<passTo.length;i++){
                System.out.println("!"+passTo[i]+"!");
            }
     
            // En une pass
            System.out.println("En une passe");
            String[] passUnique = line.substring(1,line.length()-1).split(regex);
            for (int i=0;i<passUnique.length;i++){
                System.out.println("!"+passUnique[i]+"!");
            }

  11. #11
    Rédacteur
    Avatar de thierryler
    Homme Profil pro
    Inscrit en
    Octobre 2007
    Messages
    4 078
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 078
    Points : 12 815
    Points
    12 815
    Par défaut
    Pour l'instant j'ai fais comme indiqué dans l'autre fil :

    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
     
    lines = une liste de lignes lues dans un fichiers...
    cleanLines(); // pour enlever les commentaires et les lignes vides
     
    data = new ArrayList<String[] >(cleanedLines.size());
     
    final String regex = "(^|(?<=;))([^\";])*((?=;)|$)|((?<=^\")|(?<=;\"))([^\"]|\"\")*((?=\";)|(?=\"$))";
    Pattern p = Pattern.compile(regex);
    boolean first = true;
    for (String line : cleanedLines) {
    	Matcher m = p.matcher(line);
     
    	List<String> temp = new ArrayList<String>();
    	while (m.find()) {
    		temp.add(m.group());
    	}
     
    	String[] oneData = listToArray(temp);
    	if (first) {
    		titles = oneData;
    		first = false;
    	} else {
    		data.add(oneData);
    	}
    }
    Ca ne parse donc les lignes que une par une, ce qui est très bien pour ma première version.

    L'inconvénient, c'est que la ligne suivante ne prend en compte que le point-virgule comme séparateur

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    final String regex = "(^|(?<=;))([^\";])*((?=;)|$)|((?<=^\")|(?<=;\"))([^\"]|\"\")*((?=\";)|(?=\"$))";
    Dans mon tuto, j'ai fais un mécanisme simple pour auto-deviner le bon séparateur à utiliser. Mais ça va m'obliger à avoir plusieurs regex avec les bons séparateurs.

    cf. tuto en cours d'écriture (avec plein de fautes) : http://thierry-leriche-dessirier.dev...ec-java/#LVIII

    L'étape suivante, c'est donc d'avoir des champs sur plusieurs lignes... Je vais essayer vos propositions dans la foulée...

    Th.
    Thierry Leriche-Dessirier
    Consultant Java JEE Web Agile freelance
    Rédacteur pour Developpez
    Professeur de Génie Logiciel à l'ESIEA

    Site : http://www.icauda.com / Linked'in : http://www.linkedin.com/in/thierryler / Twitter : @ThierryLeriche

  12. #12
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : Août 2005
    Messages : 2 894
    Points : 7 083
    Points
    7 083
    Par défaut
    Ca suppose que t'u as toujours les guillemets et pas de multi-ligne
    Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
    Ceylon : Installation - Concepts de base - Typage - Appels et arguments

    ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
    Une solution vous convient ? N'oubliez pas le tag
    Signature par pitipoisson

  13. #13
    Rédacteur
    Avatar de thierryler
    Homme Profil pro
    Inscrit en
    Octobre 2007
    Messages
    4 078
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 078
    Points : 12 815
    Points
    12 815
    Par défaut
    Hé hé hé, je l'ai vu venir cette question. Eh ben ça marche aussi sans. La preuve dans la dernière ligne de mon fichier CSV :

    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
     
    # Fichier avec la liste des chiens du magasin
    # Propriété de Thierry
     
    # Titres id; Prénom; Couleur et Age.
    "Id";"Prénom";"Couleur";"Age"
     
    "1";"Titi";"Jaune";"5"
    "2";"Médor";"Noir";"10"
    "3";"Pitié";"Noir";"5"
    "4";"Juju";"Gris";"5"
    "5";"Vanille";"Blanc";"7"
    "6";"Chocolat";"Marron";"12"
    "7";"Milou";"Blanc";"3"
     
    # La ligne suivante (Idefix) a trois couleur avec un point-virgule dedans
    "8";"Idefix";"Blanc; noir et beige";"14"
     
    "9";"Pluto";"Jaune";"17"
    10;Dingo;Roux;1
    Je n'ai pas pensé à vérifier si, sur une même ligne, je peux avoir des champs avec et des champs sans.

    Je dois aussi vérifier si ça marche avec des champs qui contiennent des guillemets.

    Pour la suite, je veux faire :
    * autodetection du bon séparateur ;
    * champs multilignes.

    Th.
    Thierry Leriche-Dessirier
    Consultant Java JEE Web Agile freelance
    Rédacteur pour Developpez
    Professeur de Génie Logiciel à l'ESIEA

    Site : http://www.icauda.com / Linked'in : http://www.linkedin.com/in/thierryler / Twitter : @ThierryLeriche

  14. #14
    Membre chevronné
    Inscrit en
    Mai 2006
    Messages
    1 364
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 1 364
    Points : 1 984
    Points
    1 984
    Par défaut
    Oups, désolé j'avais pas fait attention que j'etais sur le forum java (je traine sur .net et java et la, j'ai confondu ).

    Ceci dit, c'est pas difficile de passer ca en java (StringBuilder, Streams, List, ... bref rien de bien mechant).

  15. #15
    Membre confirmé
    Avatar de william44290
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Juin 2009
    Messages
    400
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France

    Informations professionnelles :
    Activité : Responsable de service informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 400
    Points : 575
    Points
    575
    Par défaut
    Les solutions les plus simple ne sont pas toujours les meilleures ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
            String regex = '"'+","+'"';
            String[] passUnique = line.substring(1,line.length()-1).split(regex);

  16. #16
    Rédacteur
    Avatar de thierryler
    Homme Profil pro
    Inscrit en
    Octobre 2007
    Messages
    4 078
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 078
    Points : 12 815
    Points
    12 815
    Par défaut
    @william44290 en fait je ne comprend même pas comment ça marche...

    si mon regex est ";" alors le guillemet de mon premier champs n'est pas netoyé ?
    Thierry Leriche-Dessirier
    Consultant Java JEE Web Agile freelance
    Rédacteur pour Developpez
    Professeur de Génie Logiciel à l'ESIEA

    Site : http://www.icauda.com / Linked'in : http://www.linkedin.com/in/thierryler / Twitter : @ThierryLeriche

  17. #17
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : Août 2005
    Messages : 2 894
    Points : 7 083
    Points
    7 083
    Par défaut
    Citation Envoyé par thierryler Voir le message
    Hé hé hé, je l'ai vu venir cette question. Eh ben ça marche aussi sans. La preuve dans la dernière ligne de mon fichier CSV :
    Je répondais à william44290 ;-) J'aurais dû citer -_-

    Citation Envoyé par william44290 Voir le message
    Les solutions les plus simple ne sont pas toujours les meilleures ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
            String regex = '"'+","+'"';
            String[] passUnique = line.substring(1,line.length()-1).split(regex);
    Citation Envoyé par Nemek Voir le message
    Ca suppose que t'u as toujours les guillemets et pas de multi-ligne
    Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
    Ceylon : Installation - Concepts de base - Typage - Appels et arguments

    ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
    Une solution vous convient ? N'oubliez pas le tag
    Signature par pitipoisson

  18. #18
    Membre confirmé
    Avatar de william44290
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Juin 2009
    Messages
    400
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France

    Informations professionnelles :
    Activité : Responsable de service informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 400
    Points : 575
    Points
    575
    Par défaut
    Dans mon tuto, j'ai fais un mécanisme simple pour auto-deviner le bon séparateur à utiliser. Mais ça va m'obliger à avoir plusieurs regex avec les bons séparateurs.
    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
     
        public static void test(){
            String line1 = '"'+"Maman"+'"'+","+'"'+"Papa"+'"'+","+'"'+"Julie, Franck et Tom"+'"'+","+'"'+"Mamy"+'"'+","+'"'+"Papy"+'"';
            String regexLine1 = '"'+","+'"';
            String[] slipLine1;
     
            String line2 = "10;Dingo;Roux;1";
            String regexLine2 = ";";
            String[] slipLine2;
     
            slipLine1=splitCVS(line1,regexLine1);
            traceResult(slipLine1);
            slipLine2=splitCVS(line2,regexLine2);
            traceResult(slipLine2);
        }
        public static String[] splitCVS(String line,String regex){
            String [] ret=null;
            int varLenRegex=0;
            if (regex.length()>1){
                varLenRegex=1;
            }
            ret=line.substring(varLenRegex,line.length()-varLenRegex).split(regex);
            return ret;
        }
        public static void traceResult(String[] values){
            System.out.println("!Trace!");
            for (int i=0;i<values.length;i++){
                System.out.println("!"+values[i]+"!");
            }
        }

  19. #19
    Rédacteur
    Avatar de thierryler
    Homme Profil pro
    Inscrit en
    Octobre 2007
    Messages
    4 078
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 078
    Points : 12 815
    Points
    12 815
    Par défaut
    @william44290 : Ah je viens de comprendre comment ça marche. Ca ne prend pas les tokens vides...

    Mais du coup, je viens de reprendre ton code :

    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
     
    public class TestCsv {
     
    	public static void test() {
    		String line1 = "\"Maman\",\"Papa\",\"Julie, Franck et Tom\",\"Mamy\",\"Papy\"";
     
    		String regexLine1 = "\",\"";
    		String[] slipLine1;
     
    		String line1b = "\"Maman\",\"Papa\",\"Julie, Franck et Tom\",,\"Papy\"";
     
    		String regexLine1b = "\",\"";
    		String[] slipLine1b;
     
    		String line2 = "10;Dingo;Roux;1";
    		String regexLine2 = ";";
    		String[] slipLine2;
     
    		String line3 = "10;Dingo;Roux;1";
    		String regexLine3 = "\";\"";
    		String[] slipLine3;
     
    		slipLine1 = splitCVS(line1, regexLine1);
    		traceResult(slipLine1);
     
    		System.out.println("********");
     
    		slipLine1b = splitCVS(line1b, regexLine1b);
    		traceResult(slipLine1b);
     
    		System.out.println("********");
     
    		slipLine2 = splitCVS(line2, regexLine2);
    		traceResult(slipLine2);
     
    		System.out.println("********");
     
    		slipLine3 = splitCVS(line3, regexLine3);
    		traceResult(slipLine3);
    	}
     
    	public static String[] splitCVS(String line, String regex) {
    		String[] ret = null;
    		int varLenRegex = 0;
    		if (regex.length() > 1) {
    			varLenRegex = 1;
    		}
    		ret = line.substring(varLenRegex, line.length() - varLenRegex).split(regex);
    		return ret;
    	}
     
    	public static void traceResult(String[] values) {
    		System.out.println("!Trace!");
    		for (int i = 0; i < values.length; i++) {
    			System.out.println(values[i]);
    		}
    	}
     
    	/**
             * @param args
             */
    	public static void main(String[] args) {
    		System.out.println("test");
    		test();
     
    	}
     
    }
    Et la sortie :

    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
     
    test
    !Trace!
    Maman
    Papa
    Julie, Franck et Tom
    Mamy
    Papy
    ********
    !Trace!
    Maman
    Papa
    Julie, Franck et Tom",,"Papy
    ********
    !Trace!
    10
    Dingo
    Roux
    1
    ********
    !Trace!
    0;Dingo;Roux;
    Ca ne correspond pas à mon besoin car, du coup les champs vides sont zappés. Et puis je ne sais pas à l'avance si je dois utiliser les guillemets ou non...
    Thierry Leriche-Dessirier
    Consultant Java JEE Web Agile freelance
    Rédacteur pour Developpez
    Professeur de Génie Logiciel à l'ESIEA

    Site : http://www.icauda.com / Linked'in : http://www.linkedin.com/in/thierryler / Twitter : @ThierryLeriche

  20. #20
    Membre confirmé
    Avatar de william44290
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Juin 2009
    Messages
    400
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France

    Informations professionnelles :
    Activité : Responsable de service informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 400
    Points : 575
    Points
    575
    Par défaut
    Peux tu tester cela (le même avec sélecteur automatique ...) Merci :

    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
        public static void test(){
            String line0 ="# commentaires blabla. ; ";
            String line1 ="";
            String line2 = '"'+"Maman"+'"'+","+'"'+"Papa"+'"'+","+'"'+""+'"'+","+'"'+"Julie, Franck et Tom"+'"'+","+'"'+"Mamy"+'"'+","+'"'+"Papy"+'"';
            String line3 = '"'+"France"+'"'+";"+'"'+"Jacques"+'"'+";"+'"'+""+'"'+";"+'"'+"Renée; Marcel et Tom"+'"'+";"+'"'+"Simone"+'"'+";"+'"'+"Papy"+'"';
            String line4 = "10;Dingo;Roux;;1";
            String line5 = "11,Donal,Noir,2,";
     
            traceResult(splitCVS(line0));
            traceResult(splitCVS(line1));
            traceResult(splitCVS(line2));
            traceResult(splitCVS(line3));
            traceResult(splitCVS(line4));
            traceResult(splitCVS(line5));
        }
        public static String[] splitCVS(String line){
            String[] ret=null;
            //
            String comment="#";
            String regex1 = '"'+","+'"';
            String regex2 = '"'+";"+'"';
            String regex3 = ",";
            String regex4 = ";";
            //
            int varLenRegex=0;
            String regex = null;
     
            int soluce=0;
            if (soluce==0 && line==null){
                soluce=1;
            }
            if (soluce==0 && line.length()==0){
                soluce=1;
            }
            if (soluce==0 && line.trim().startsWith(comment)){
                soluce=1;
            }
            if (soluce==0 && line.contains(regex1)){
                soluce=10;
                regex=regex1;
            }
            if (soluce==0 && line.contains(regex2)){
                soluce=20;
                regex=regex2;
            }
            if (soluce==0 && line.contains(regex3)){
                soluce=30;
                regex=regex3;
            }
            if (soluce==0 && line.contains(regex4)){
                soluce=40;
                regex=regex4;
            }
            if (soluce>1){
                if (regex.length()>1)
                    varLenRegex=1;
                ret=line.substring(varLenRegex,line.length()-varLenRegex).split(regex);
            }
            return ret;
        }
        public static void traceResult(String[] values){
            System.out.println("\n");
            if (values!=null)
                for (int i=0;i<values.length;i++)
                    System.out.println("!"+values[i]+"!");
        }

Discussions similaires

  1. [XL-2010] Convertir plusieurs fichiers excel en csv avec des guillemets
    Par karido-74 dans le forum Macros et VBA Excel
    Réponses: 41
    Dernier message: 29/01/2014, 18h32
  2. [CSV] importation CSV avec des guillemets
    Par trash_board dans le forum Langage
    Réponses: 3
    Dernier message: 12/09/2006, 14h08
  3. Réponses: 9
    Dernier message: 28/10/2005, 11h43
  4. [C#] Prob IndexOf sous Pocket Pc avec des guillemets
    Par freddyboy dans le forum Windows Mobile
    Réponses: 7
    Dernier message: 10/06/2004, 09h57

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