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

Langage Java Discussion :

[Regex] Simple split


Sujet :

Langage Java

  1. #1
    Candidat au Club
    Homme Profil pro
    Analyse système
    Inscrit en
    Août 2014
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Analyse système

    Informations forums :
    Inscription : Août 2014
    Messages : 3
    Points : 2
    Points
    2
    Par défaut [Regex] Simple split
    Bonjour,

    J'ai cette phrase

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Objet[id=100,name=car,type=grey,source=sourceId{id=12,version=12},linked=true]
    J'aimerai trouver deux regex, chacun me permettant d'obtenir les attributs ou les valeurs en utilisant un split, la difficulte se trouve sur l'attribut sourceId car il contient le signe = mais je ne veux pas spliter ce qu'il y a l'interieur.

    En example

    Split avec le regex 1
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [0]id [1]name [2]type [3]sourceId [4]linked
    Split avec le regex 2
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [0]100 [1]car[2]grey[3]sourceId{id=12,version=12}[4]true
    Je pourais otenir les valeurs avec ce regex la http://regexr.com/3c996 mais il splitera aussi l'interieur de l'attribut sourceId

    Merci!

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Salut,

    Personnellement, je fais ce genre de chose plutôt avec un automate à état.

    A supposer qu'on n'ait pas plusieurs niveaux d'imbrication de groupes de propriétés entre accolades (genre source=sourceId{id=12,version=12,source=sourceId{id=11,version=2}}), je ne sais pas si on peut trouver plus simple avec des expressions régulières (ça m'intéresse) :

    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
    public static void main(String[] args) { 
     
        final String s = "Objet[id=100,name=car,type=grey,source=sourceId{id=12,version=12},linked=true]";
     
        final Matcher matcherLevel1 = Pattern.compile("\\w+" // une suite d'au moins une lettre
                                                    + "?=" // jusqu'au = suivant
                                                    + "(" // suivi ...
                                                    +   "\\p{Alnum}" // ... d'une lettre ou un chiffre 
                                                    +   "|" // ... ou d'un ...
                                                    +     "("
                                                    +       "\\{.*?\\}" // ... nombre quelconque de caractères entre accolades (sauf accolade fermante)
                                                    +     ")"
                                                    + ")" // fin de capture
                                                    + "+" // au moins une fois
                                                     ).matcher(s);
     
        while( matcherLevel1.find() ) {
            String[] split = matcherLevel1.group().split("=", 2);
            System.out.println("Property: " + split[0] + " Value: " + split[1]);
        }
     
    }
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  3. #3
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 858
    Points : 6 556
    Points
    6 556
    Par défaut
    Oui tu peux faire un peu plus simple: au lieu de capturer l'ensemble (clef=valeur) dans la première pattern, capture la clef et la valeur séparément: (clef)=(valeur) comme ça pas besoin de faire un split ensuite. Sinon, je retirerai le premier ? qui est inutile et je remplacerai .*? par [^}]* pour éviter le quantificateur non gourmand.

    Moins simple mais plus robuste, on parcourt la chaîne en utilisant l'ancre \G en partant de Objet[ jusqu'au crochet fermant, ce qui permet de s'assurer que les clefs/valeurs relevées en font bien partie et que le format à l'intérieur des crochets est bien celui que l'on attend de bout en bout. J'ajouterai une version plus tard.
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  4. #4
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par CosmoKnacki Voir le message
    Oui tu peux faire un peu plus simple: au lieu de capturer l'ensemble (clef=valeur) dans la première pattern, capture la clef et la valeur séparément: (clef)=(valeur) comme ça pas besoin de faire un split ensuite.
    Je voulais éviter d'avoir à faire une boucle +=2, mais c'est vrai qu'on peut aussi faire ((clef)=(valeur)), et utiliser getGroup(1)/getGroup(2).
    Sinon, je retirerai le premier ? qui est inutile
    Je l'avais mis pour éviter de matcher jusqu'au dernier =, mais c'est vrai que rien ne matche la virgule (,) dans le la partie valeur, donc ça ne peut aller jusque là.

    et je remplacerai .*? par [^}]* pour éviter le quantificateur non gourmand.
    Tiens, j'aurais dit que du coup on capturerait que "sourceId{id=12,version=12", donc sans l'accolade de fin.

    Sinon moins simple mais plus robuste, on parcourt la chaîne en utilisant l'ancre \G en partant de Objet[ jusqu'au crochet fermant, ce qui permet de s'assurer que les clefs/valeurs relevées en font bien partie et que le format à l'intérieur des crochets est bien celui que l'on attend. J'ajouterai une version plus tard.
    L'ancre \G est bien un truc dont je n'ai jamais compris pas le principe : je n'ai jamais réussi à faire fonctionner mes essais avec \G. Et j'ai beau voir des exemples qui fonctionnent, je ne comprends toujours pas le fonctionnement. Tu aurais un lien sur une doc qui explique bien le principe de \G ?
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  5. #5
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 858
    Points : 6 556
    Points
    6 556
    Par défaut
    Franchement un tutoriel avec une top explication sur l'utilisation de \G, je ne me rappelle pas en avoir déjà vu.

    Il y a http://www.rexegg.com/regex-anchors.html#G (en anglais). C'est un site qui est plutôt orienté PCRE à l'origine (à l'origine c'était un blog un peu fourre-tout où on pouvait trouver aussi des rythmes de percussions d'Afrique de l'ouest) avec des exemples simples, quelque cas d'utilisations, mais malheureusement rien en particulier sur comment rompre la contiguïté, et sur comment s'assurer qu'on est bien arriver au bout de ce qu'on voulait extraire.

    Moi, c'est à force d'essais que j'ai fini par trouver des ruses, suivant les situations, pour que la pattern s'arrête au bon moment et pour en avoir confirmation.


    Un schéma type pour trouver plusieurs cibles entre deux bornes comme ici est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (?: \G(?!\A) partie_entre_les_cibles | amorce) (cible) (?:(?=(fin))?
    Après suivant les cas, telle ou telle partie peut être enlevée. Chaque élément doit être décrit avec précision notamment la cible et la partie entre les cibles pour éviter qu'aucune d'elles ne puisse matcher la fin afin de rompre la contiguïté. C'est pour cette raison aussi que la fin est placée dans un lookahead (pour ne pas faire partie de la correspondance). Ce lookahead est lui-même placé dans un groupe optionnel pour ne pas gêner les matches successifs, et c'est seulement sur le dernier item que ce lookahead réussit. La capture de la fin sert alors de confirmation que la borne de fin à bien été atteinte et que le format est bien conforme.

    Ce qui ici donne (en doublant les antislashes pour les strings Java):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    (?:\G(?!\A) , | \bObjet\[ ) 
            #   ^       ^
            #   |       +------> amorce
            #   +------> truc entre les cibles
     
    # cible
    (?<key> [^]=,]*+ ) = (?<value> [^],{]*+ (?:\{[^}]*} [^],{]*)*+ )
     
    # test sur la borne de fin
    (?:(?=(?<fin>])))?
    Et si je lui passe une chaîne mal formatée comme par exemple: Objet[key1=val1,key2=key2=val2] le groupe fin n'existera jamais et donc au terme de ma boucle sur m.find(), je peux refuser l'ensemble des clefs/valeurs trouvées puisque le format n'est pas valide, voire lever une exception.
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  6. #6
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Merci pour les explications. Je vais voir si je capte avec ça.

    Le site de référence que j'utilise et qui m'a permis de comprendre clairement l'usage des "positives/negatives look-ahead", c'est ça, mais je n'y ai rien trouvé sur \G, y compris dans la section Anchors.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  7. #7
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 858
    Points : 6 556
    Points
    6 556
    Par défaut
    Sur ce site l'ancre \G est décrite dans la section Continuing Matches. Mais c'est le néant point de vue exemples.
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  8. #8
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par CosmoKnacki Voir le message
    Sur ce site l'ancre \G est décrite dans la section Continuing Matches.
    Ah, bah, ouais, la dernière section ! Je n'y suis pas encore arrivé, j'en ai encore à potasser (j'en suis aux récursions, que je ne pensais pas possibles avant de tomber sur ce site), alors forcément... Merci !!!
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  9. #9
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 858
    Points : 6 556
    Points
    6 556
    Par défaut
    Malheureusement les récursions ne fonctionnent pas en Java.
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  10. #10
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Ouais, je viens de lire la page, bah, pour le coup, là, ce n'est pas beaucoup plus explicatif que le laconique "The end of the previous match" de la javadoc, et effectivement le manque d'exemples fait que je ne vois pas plus comment m'en servir.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  11. #11
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par CosmoKnacki Voir le message
    Malheureusement les récursions ne fonctionnent pas en Java.
    Argh ! Je peux sauter les deux sections, alors.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  12. #12
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 858
    Points : 6 556
    Points
    6 556
    Par défaut
    Oui celles-là tu peux, effectivement. Par contre les particularités intéressantes du moteur de regex Java (que l'on ne retrouve pas dans PCRE par exemple) sont: Les lookbehinds de taille variable mais limitée (on peut écrire (?<=a{1,100})b) et les soustractions et intersections de classes de caractères.
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

Discussions similaires

  1. [TOS 3.1.2] - [TMap] - faire un simple split sur un String
    Par spidetra dans le forum Développement de jobs
    Réponses: 0
    Dernier message: 24/09/2009, 10h55
  2. [RegEx] Regex simple: Verfier premier caractère d'une chaine.
    Par yann123456 dans le forum Langage
    Réponses: 2
    Dernier message: 07/04/2009, 15h50
  3. [RegEx] Regex simple qui ne fonctionne pas
    Par Bruno.C dans le forum Langage
    Réponses: 4
    Dernier message: 03/12/2008, 15h05
  4. [RegEx] regex simple qui ne marche pas (encore)
    Par denisvignes dans le forum Langage
    Réponses: 5
    Dernier message: 19/09/2008, 15h04
  5. [RegEx] Regex et split
    Par Gamez29 dans le forum Langage
    Réponses: 1
    Dernier message: 06/06/2007, 11h53

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