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 :

Expression régulière "non greedy" en Java


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Février 2008
    Messages
    31
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 31
    Par défaut Expression régulière "non greedy" en Java
    Bonjour,

    J'aimerai pouvoir récupérer la petite chaine de caractère qui commence par 'd' fini par 'a' et contient 'o'

    Exemple : "fondjswxaeqobdnoajezbpfrehanxi" => "dnoa"

    Voilà mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Pattern pattern = Pattern.compile("d.*?o.*?a");
    Matcher matcher = pattern.matcher("fondjswxaeqobdnoajezbpfrehanxi");
    while (matcher.find()) {
      system.out.println(matcher.group());
    }
    Ce code affiche "djswxaeqobdnoa" et non "dnoa".

    Comment faire pour bien retourner la plus petite ?

    Merci

  2. #2
    Membre averti
    Inscrit en
    Février 2008
    Messages
    31
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 31
    Par défaut
    La solution :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    String shortest = null;
    Pattern pattern = Pattern.compile("(?=(d.*?o.*?a))");
    Matcher matcher = pattern.matcher("ondjswxaeqobdnoajezbpfrehanxi");
    while (matcher.find()) {
    for (int i = 1; i <= matcher.groupCount(); i++) {
        if (shortest == null || matcher.group(i).length() < shortest.length()) {
            shortest = matcher.group(i);
        }
    }

  3. #3
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 582
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    Par défaut
    Joli trick avec le positive lookahead pour forcer find() à avancer caractère par caractère .

    Mais il est inutile de boucler sur les groupes : il n'y en a qu'un, et c'est le numéro 1. Il suffit de faire ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    String shortest = null;
    Pattern pattern = Pattern.compile("(?=(d.*?o.*?a))");
    Matcher matcher = pattern.matcher("ondjswxaeqobdnoajezbpfrehanxi");
    while (matcher.find()) {
      String candidate = matcher.group(1);
      if (shortest == null || candidate.length() < shortest.length()) {
        shortest = candidate;
      }
    }
    Comme je n'aime pas trop les tricks et je préfère garder un programme simple à lire et qui exprime clairement mon intention, voici comment j'aurais fait sans modifier la regex :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    String shortest = null;
    Pattern pattern = Pattern.compile("d.*?o.*?a");
    Matcher matcher = pattern.matcher("ondjswxaeqobdnoajezbpfrehanxi");
     
    int start = 0;
    while (matcher.find(start)) {
      String candidate = matcher.group();
      if (shortest == null || candidate.length() < shortest.length()) {
        shortest = candidate;
      }
      start = matcher.start()+1;
    }
    Pareil, find() n'avance que d'un caractère à la fois.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  4. #4
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Ou plus simplement

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Pattern pattern = Pattern.compile("d[^d]*?o.[^a]*?a");
    Matcher matcher = pattern.matcher("fondjswxaeqobdnoajezbpfrehanxi");
    while (matcher.find()) {
      system.out.println(matcher.group());
    }

  5. #5
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 582
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    Par défaut
    Hum. Je comprends pas trop l'intérêt du [^a], je suppose que c'est une erreur d'inattention.

    Mais sinon je vois l'idée : "invalider la recherche si on trouve un d entre le premier d et le o, pour s'assurer d'avoir le plus court."
    Ouais, ok, mais alors... Entre le o et le a, il faut rejeter toute séquence valide de d suivi de o... Ça peut se faire, avec un negative lookbehind. Mais "plus simplement" je suis pas convaincu.

    La regex donnée en exemple ne trouve pas le plus court. (précisément parce qu'on tombe sur une séquence de d suivi de o, qui elle-même est suivie d'une autre séquence de d suivi de o, avant de tomber sur le a.)
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  6. #6
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Ha oui tiens, au temps pour moi

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. expression régulière décimale non fonctionnelle
    Par drumtof dans le forum Général JavaScript
    Réponses: 9
    Dernier message: 10/09/2009, 11h01
  2. Expression Régulière avec Quote
    Par jon301 dans le forum Langage
    Réponses: 3
    Dernier message: 25/10/2006, 22h08

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