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

avec Java Discussion :

corriger les erreurs d'espace commises dans une phrase


Sujet :

avec Java

  1. #1
    Membre régulier
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2008
    Messages
    207
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2008
    Messages : 207
    Points : 114
    Points
    114
    Par défaut corriger les erreurs d'espace commises dans une phrase
    Bonjour,

    Je suis en train de réfléchir à la manière de transformer une String mal tapée (avec des espaces mal placés, ou manquants) pour obtenir au final une String bien tapée.

    Si, par exemple, je tape: "Ce matin ,il faisait beau, mais cet après-midi, il risque de pleuvoir ."

    Je désire donc rajouter l'espace après la première virgule, supprimer l'espace avant la première virgule, supprimer un espace avant "après-midi" et supprimer l'espace avant le point final.

    Alors plusieurs idées me viennent, mais je ne vois pas encore vraiment comment faire.

    Taper une String comportant des erreurs.
    La transformer en char.
    Créer une ArrayList dans laquelle je stocke les char.
    Avec un Iterator, regarder:
    Si je trouve deux espaces d'affilés, en supprimer un.
    Si je trouve un espace avant une virgule, un point, un point virgule etc., le supprimer.
    Si je ne trouve pas d'espace après une virgule, un point, un point virgule etc., en rajouter un.
    Du coup, j'obtiens normalement une ArrayList de char avec les espaces bien placés.
    Et là, je recrée une String dans laquelle je recopie les char un par un.

    Est-ce que vous auriez une idée moins tordue? J'ai l'impression qu'il y a bien plus simple que ce que je désire faire, peut-être avec charAt.

    Merci d'avance,
    Johnny3

  2. #2
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 10
    Points : 11
    Points
    11
    Par défaut
    regarde les regular expression.

    java.util.regex.Pattern et classes apparentées.

    C'est fait pour se genre de chose, tu aurais quelquechose de plus souple, et probablement plus optimiser. Par contre il faut se farcir l'api un peu complexe des qu'on veut faire des choses compliquées.

    Maintenant si tu veux faire simple toujours dans les regexp il est possible qu'un bete String.replaceAll() puisse suffire.

  3. #3
    Membre chevronné

    Homme Profil pro
    Architecte logiciel
    Inscrit en
    Novembre 2006
    Messages
    1 252
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte logiciel
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 252
    Points : 1 954
    Points
    1 954
    Par défaut
    Le procédé est le bon. Mais pour n'oublier aucun cas, une modélisation à l'aide d'un automate peut aider.

  4. #4
    Expert éminent sénior
    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 : 45
    Localisation : Belgique

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    commence par une regexp qui remplace les espaces multiples par un espace simple, poursuit avec un regexp qui transforme les blanc+ponctuation par une ponctuation simple, et fini avec un regexp qui transforme les ponctuation + caractère en ponctuation + espace + caractère. Ca devrait être bon

  5. #5
    Membre régulier
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2008
    Messages
    207
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2008
    Messages : 207
    Points : 114
    Points
    114
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    commence par une regexp qui remplace les espaces multiples par un espace simple, poursuit avec un regexp qui transforme les blanc+ponctuation par une ponctuation simple, et fini avec un regexp qui transforme les ponctuation + caractère en ponctuation + espace + caractère. Ca devrait être bon
    Merci! Merci à tous. Je vais lire cette fameuse classe regexp et je vous dis si j'y arrive.

    Sinon, quelque chose avec StringTokenizer est-il envisageable?

    Johnny3

  6. #6
    Membre expérimenté Avatar de herve91
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    1 282
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 282
    Points : 1 608
    Points
    1 608
    Par défaut
    Citation Envoyé par johnny3 Voir le message
    Taper une String comportant des erreurs.
    La transformer en char.
    Créer une ArrayList dans laquelle je stocke les char.
    Avec un Iterator, regarder:
    ...
    Un StringBuffer / StringBuilder pour construire ta chaîne bien tapée devrait suffire.

  7. #7
    Membre chevronné

    Homme Profil pro
    Architecte logiciel
    Inscrit en
    Novembre 2006
    Messages
    1 252
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte logiciel
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 252
    Points : 1 954
    Points
    1 954
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    commence par une regexp qui remplace les espaces multiples par un espace simple, poursuit avec un regexp qui transforme les blanc+ponctuation par une ponctuation simple, et fini avec un regexp qui transforme les ponctuation + caractère en ponctuation + espace + caractère. Ca devrait être bon
    Ca me parraît bien couteux...

  8. #8
    Expert éminent sénior
    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 : 45
    Localisation : Belgique

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    pas temps que çà, et c'est probablement plus lisible que de tapper tout dans une seule regexp

  9. #9
    Membre régulier
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2008
    Messages
    207
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2008
    Messages : 207
    Points : 114
    Points
    114
    Par défaut
    je n'y arrive pas! voici ce que j'ai fait pour le moment:

    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
    import java.util.*;
    import java.io.*;
    import java.util.regex.*;
     
    public class Exo13 {
     
     
     
     
    	public static void main(String args[]) {
     
    		String StringTapee;
    		Terminal.ecrireStringln("Votre String?");
    		StringTapee = Terminal.lireString();
    		StringTokenizer st = new StringTokenizer(StringTapee,"  ");
     
    		while (st.hasMoreTokens()) {
    			System.out.print(st.nextToken() + " ");
    		}
     
     
     
    	// compilation de la regex avec le motif : "thé"
    		Pattern p = Pattern.compile(" .");
    		// création du moteur associé à la regex sur la chaîne "J’aime le thé."
    		Matcher m = p.matcher("J’aime le thé .");
    		// remplacement de toutes les occurrences de "thé" par "chocolat"
    		String s = m.replaceAll(". ");
    	    System.out.println(s);
     
    	}
    }
    et ça me renvoie ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Votre String?
        ça ne    fonctionne pas!
    ça ne fonctionne pas! J’aime. e. hé.
    Le résultat est parfait avec StringTokenizer pour les espaces en trop (mais je ne sais pas comment gérer la même chose pour régler les problèmes d'espace avant les ponctuations) mais je ne sais comment récupérer le tout sous la forme d'une String.

    Avec regexp, je dois mal comprendre car avec un essai, ça ne fonctionne pas. Comment faire? Aurais-tu un exemple concret, tchize?

    Comment utilise-t-on un StringBuffer / StringBuilder, herve91?

    Dur dur l'informatique

    Johnny3

  10. #10
    Membre expérimenté Avatar de herve91
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    1 282
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 282
    Points : 1 608
    Points
    1 608
    Par défaut
    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
    public String normalize(String in) {
       int len = in.length();
       StringBuffer out = new StringBuffer(len);
     
       boolean spaceNeeded = false;
     
       for (int i = 0; i < len; i++) {
          char c = in[i];
          if (c == ' ') {
             spaceNeeded = true;
          } else {
             boolean ponct = c == ',' || c == '.';
             if (spaceNeeded && !ponct) {
                out.append(' ');
             }
             out.append(c);
             spaceNeeded = ponct;
          }
       }
       return out.toString();
    }

  11. #11
    Expert éminent sénior
    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 : 45
    Localisation : Belgique

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    Citation Envoyé par johnny3 Voir le message
    et ça me renvoie ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Votre String?
        ça ne    fonctionne pas!
    ça ne fonctionne pas! J’aime. e. hé.
    Ce qui est ce que tu a demandé. Le "." si tu lit la doc des regexp, signifie "n'importe quel caractère". Tu a demandé de remplacer "espace suivi de n'importe quel caractère" par "point espace".

    Un exemple de regexp correcte:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    message = message.replaceAll("\\s*"," ")  // remplace les whitespaces doubles
    message = message.replaceAll("\\s+(\\p{Punct})\\s*","$1 "); / remplace les espaces avant ponctuation par espaces après
    // etc.

  12. #12
    Membre régulier
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2008
    Messages
    207
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2008
    Messages : 207
    Points : 114
    Points
    114
    Par défaut
    Citation Envoyé par herve91 Voir le message
    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
    public String normalize(String in) {
       int len = in.length();
       StringBuffer out = new StringBuffer(len);
     
       boolean spaceNeeded = false;
     
       for (int i = 0; i < len; i++) {
          char c = in[i];
          if (c == ' ') {
             spaceNeeded = true;
          } else {
             boolean ponct = c == ',' || c == '.';
             if (spaceNeeded && !ponct) {
                out.append(' ');
             }
             out.append(c);
             spaceNeeded = ponct;
          }
       }
       return out.toString();
    }
    Merci beaucoup, par contre, je n'ai pas réussi à faire fonctionner le code que tu as mis.

    Je l'ai utilisé mais une erreur a été soulevée: char c = in[i]; car in est de type String. J'ai donc changé public String normalize(String in) en public String normalize(char [] in), mais en exécutant, j'ai obtenu la même chose que la phrase tapée. Où ai-je fait une erreur?

  13. #13
    Membre expérimenté Avatar de herve91
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    1 282
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 282
    Points : 1 608
    Points
    1 608
    Par défaut
    Non, c'est moi, j'ai été un peu vite, une String n'est pas un tableau
    j'ai obtenu la même chose que la phrase tapée
    Il faut utiliser le retour de la méthode normalize() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    String chaineNormalisee = normalize(chaineEnEntree);
    System.out.println(chaineNormalisee);

  14. #14
    Membre régulier
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2008
    Messages
    207
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2008
    Messages : 207
    Points : 114
    Points
    114
    Par défaut
    Citation Envoyé par herve91 Voir le message
    Non, c'est moi, j'ai été un peu vite, une String n'est pas un tableau
    Il faut utiliser le retour de la méthode normalize() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    String chaineNormalisee = normalize(chaineEnEntree);
    System.out.println(chaineNormalisee);
    Je ne sais comment te remercier! J'ai simplement eu à faire quelques tous petits changements (dans le boolean, j'ai rajouté les ;, !, ? etc, et j'ai retourné out.toString().trim() pour virer les espaces de début et de fin) et ça marche! J'ai testé toutes les erreurs possibles et imaginables et ça me sort toujours une phrase parfaite! Merci beaucoup!

    Johnny3

  15. #15
    Membre expérimenté Avatar de herve91
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    1 282
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 282
    Points : 1 608
    Points
    1 608
    Par défaut
    N'oublie pas le bouton

  16. #16
    Membre régulier
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2008
    Messages
    207
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2008
    Messages : 207
    Points : 114
    Points
    114
    Par défaut
    Citation Envoyé par herve91 Voir le message
    N'oublie pas le bouton
    En fait, heureusement que je l'ai oublié, car j'ai passé une partie de l'après-midi à chercher comment mettre un espace avant les points d'interrogation et d'exclamation.

    Car dans le code, s'il y a un ! ou un ?, et plusieurs espaces faits avant, c'est ok, un seul espace est mis, mais si on n'en met aucun, le ! ou le ? sont collés au mot.

    J'ai vérifié avec word, il faut les séparer du mot.

    Donc je cherche comment faire... En tout cas, très ingénieux, ton code, sincèrement.

    Johnny3

  17. #17
    Membre expérimenté Avatar de herve91
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    1 282
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 282
    Points : 1 608
    Points
    1 608
    Par défaut
    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
    public String normalize(String in,
    			String noSpaceBefore,
    			String spaceBefore,
    			String spaceAfter) {
    	int len = in.length();
    	StringBuffer out = new StringBuffer(len);
     
    	boolean spaceNeeded = false;
     
    	for (int i = 0; i < len; i++) {
    		char c = in.charAt(i);
    		if (c == ' ') {
    			spaceNeeded = true;
    		} else {
    			if ((spaceNeeded && noSpaceBefore.indexOf(c) < 0)
    				|| spaceBefore.indexOf(c) >= 0) {
    				out.append(' ');
    			}
    			out.append(c);
    			spaceNeeded = spaceAfter.indexOf(c) >= 0;
    		}
    	}
    	return out.toString().trim();
    }
     
    public String normalize(String in) {
    	return normalize(in, ",.", ";:?!", ",.;:?!");
    }

  18. #18
    Membre régulier
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2008
    Messages
    207
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2008
    Messages : 207
    Points : 114
    Points
    114
    Par défaut
    Formidable, ça marche! Par contre, juste une question, qu'est-ce que ça change de modifier le programme de la sorte:
    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 String normalize(String in,
    			String noSpaceBefore,
    			String spaceBefore,
    			String spaceAfter) {
    //	int len = in.length();
    //	StringBuffer out = new StringBuffer(len);
            String out = "";
     
    	boolean spaceNeeded = false;
     
    	for (int i = 0; i < len; i++) {
    		char c = in.charAt(i);
    		if (c == ' ') {
    			spaceNeeded = true;
    		} else {
    			if ((spaceNeeded && noSpaceBefore.indexOf(c) < 0)
    				|| spaceBefore.indexOf(c) >= 0) {
    				out += " ";
    			}
    			out += c;
    			spaceNeeded = spaceAfter.indexOf(c) >= 0;
    		}
    	}
    	return out.trim();
    }
     
    public String Normalize(String in) {
    	return normalize(in, ",.", ";:?!", ",.;:?!");
    }
    En un autre sens, qu'apporte le StringBuffer? (je ne suis pas encore familiarisé avec le concept, et je n'ai pas tout saisi sur API) Je sais que Buffer signifie Tampon, mais pourquoi doit-on l'utiliser?

    Merci encore, vraiment,
    Johnny3

  19. #19
    Membre expérimenté Avatar de herve91
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    1 282
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 282
    Points : 1 608
    Points
    1 608
    Par défaut
    Pour améliorer le temps de traitement. StringBuffer est en qq sorte une String modifiable, il dispose d'un buffer de caractères en interne qui est agrandi en fonction des besoins. Contrairement à String qui est une classe immuable, une fois l'objet créé, il n'est pas modifiable. Quand tu fais "out += c" tu crées une nouvelle String, concaténation de l'ancienne String "out" et du caractère "c". En plus, dans une boucle, cela fait énormément de créations d'objets et de recopies inutiles. Donc toujours utiliser StringBuffer en lieu et place de String lorsqu'on fait de la concaténation au sein d'une boucle.

  20. #20
    Membre régulier
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2008
    Messages
    207
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2008
    Messages : 207
    Points : 114
    Points
    114
    Par défaut
    Citation Envoyé par herve91 Voir le message
    Pour améliorer le temps de traitement. StringBuffer est en qq sorte une String modifiable, il dispose d'un buffer de caractères en interne qui est agrandi en fonction des besoins. Contrairement à String qui est une classe immuable, une fois l'objet créé, il n'est pas modifiable. Quand tu fais "out += c" tu crées une nouvelle String, concaténation de l'ancienne String "out" et du caractère "c". En plus, dans une boucle, cela fait énormément de créations d'objets et de recopies inutiles. Donc toujours utiliser StringBuffer en lieu et place de String lorsqu'on fait de la concaténation au sein d'une boucle.
    ok. Merci beaucoup!

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

Discussions similaires

  1. Réponses: 0
    Dernier message: 24/05/2011, 13h19
  2. Corriger les erreurs d'orthographe dans Texniccenter
    Par open_source dans le forum Débuter
    Réponses: 1
    Dernier message: 19/05/2009, 11h35
  3. Supprimer les espaces consécutifs dans une chaîne
    Par aymenet1 dans le forum Pascal
    Réponses: 12
    Dernier message: 27/11/2007, 23h21
  4. Réponses: 3
    Dernier message: 26/03/2007, 10h46

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