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] Comment gérer les caractères d'échappement ?


Sujet :

Collection et Stream Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de fedfil
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    91
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 91
    Par défaut [RegEx] Comment gérer les caractères d'échappement ?
    Bonjour à tous,

    J'avoue avoir encore des difficultés à gérer les regex.
    J'aurais donc besoin de vos conseils.

    Je récupère une chaine de caractère sous la forme "nom" <email@email.com>
    Je souhaiterai récupérer seulement le nom et l'email contenu dans cette chaine.

    Simple me direz-vous !? Il suffit d'avoir un regex sous la forme suivante (ou quelquechose qui y ressemble fortement) :
    Ok sans les caractères d'échapements !! En effet il est possible dans le nom d'avoir un guillemet. Dans ce cas là, un anti-slash nommé caractère d'échapement doit être avant le guillement.
    Ex: "nom \"prenom\"" <email@email.com> est aussi une adresse valide. Et là, le bas blesse parce qu'il n'est pas possible d'utiliser une regex.

    J'ai préféré donc le "gérer à la main" de la façon suivante :
    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
        /**
         * Méthode qui à partir d'un header de mail retourne l'adresse mail<br>
         * pattern sous la forme "name" <email@email.com><br>
         * Caractère d'échapement : \ Le caractère à la suite d'un \ n'est pas pris en compte
         * @param header
         * @return
         */
        private static String retrieveEmailFromHeader(String header) {
        	StringBuffer nameBuffer = new StringBuffer();
        	StringBuffer mailBuffer = new StringBuffer();
        	boolean isName = false;
        	boolean isMail = false;    	   
        	int i = 0;
        	while (i < header.length()) {
        		if ((!isName) && (!isMail) && (header.charAt(i) == '\"')) {
        			isName = true;
        		} else if (isName && (header.charAt(i) == '\\')) {
        			i++;
        			if (i < header.length()) {
        				nameBuffer.append(header.charAt(i));
        			}     			
        		} else if (isName && (header.charAt(i) == '\"')) {
        			isName = false;
        		} else if (isName) {
        			nameBuffer.append(header.charAt(i));
        		} else if ((!isName) && (!isMail) && (header.charAt(i) == '<')) {
        			isMail = true;
        		} else if (isMail && (header.charAt(i) == '>')) {
        			isMail = false;
        		} else if (isMail) {
        			mailBuffer.append(header.charAt(i));
        		} 
       			i++;
        	}
        	log.debug("retrieveEmailFromHeader("+header+")="+nameBuffer+", "+mailBuffer);
        	return  mailBuffer.toString();   	
        }
    Mon parseur gère parfaitement parfaitement les caractères d'échappement.

    Est-il possible de faire la même chose avec un regex ?

    Pour ma culture, merci

  2. #2
    Membre Expert
    Homme Profil pro
    Directeur technique
    Inscrit en
    Janvier 2007
    Messages
    1 348
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 348
    Par défaut
    Je n'ai pas compris pourquoi dans ton cas précis les caractères d'échappement te gênent ... En effet, ils sont à l'intérieur et tu pourrais considérer par exemple que la fin de la section nom est le < (qui j'imagine est interdit dans un nom).

    Mais ta question reste valide dans l'absolu, et là malheureusement je ne sais pas ... Mais je me dis qut en plaçant dans un forum PERL tu aurais sûrement plus de chances ^^

  3. #3
    Expert confirmé
    Avatar de le y@m's
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2005
    Messages
    2 636
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Février 2005
    Messages : 2 636
    Par défaut
    Citation Envoyé par fedfil
    Ex: "nom \"prenom\"" <email@email.com> est aussi une adresse valide. Et là, le bas blesse parce qu'il n'est pas possible d'utiliser une regex.
    Il est tout à fait possible d'utiliser les expressions régulières dans ce cas.
    Petit exemple avec les classes Matcher et Pattern
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    String name = null;
    String email = null;
    Matcher matcher = Pattern.compile("\".*\"").matcher(header);
    if(matcher.find()) {
        name = matcher.group().replaceAll("\"(.*)\"", "$1");;
    }
    matcher = Pattern.compile("<.*>").matcher(header);
    if(matcher.find()) {
        email = matcher.group();
    }
    Je ne répondrai à aucune question technique par MP.

    Pensez aux Tutoriels et aux FAQs avant de poster ;) (pour le java il y a aussi JavaSearch), n'oubliez pas non plus la fonction Rechercher.
    Enfin, quand une solution a été trouvée à votre problème
    pensez au tag :resolu:

    Cours Dvp : http://ydisanto.developpez.com
    Blog : http://yann-disanto.blogspot.com/
    Page perso : http://yann-disanto.fr

  4. #4
    Membre confirmé Avatar de fedfil
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    91
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 91
    Par défaut
    salut,

    Excusez-moi je n'avais pas vu vos réponses.
    Merci donc pour vos précisions !! Les regex sont vraiment trop flous pour moi.

    @chtig : et non, le caractère "<" est malheuresement autorisé.
    @y@m's : merci pour le bout de code. J'ai fait le test : le nom est bien récupéré mais pas le reste.

    Cas de test
    - header : "dev-<ufe>-\"dsd\"" <test@test.com>
    - nom : dev-<ufe>-\"dsd\" (parfait)
    - mail : <ufe>-\"dsd\"" <neb-in@etso.rte-france.com>

    Il prend donc le premier caractère "<". Normal. J'ai toujours pas la solution en regex pour lui dire "tu prends l'email après avoir pris le nom". Une idée ?

    Merci.

  5. #5
    Expert confirmé
    Avatar de le y@m's
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2005
    Messages
    2 636
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Février 2005
    Messages : 2 636
    Par défaut
    Effectivement, ce sont les <> dans le nom qui pose problème.
    Essaye ça (pas testé) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    String name = null;
    String email = null;
    Matcher matcher = Pattern.compile("\".*\"").matcher(header);
    if(matcher.find()) {
        name = matcher.group().replaceAll("\"(.*)\"", "$1");;
    }
    matcher = Pattern.compile("<.*>").matcher(header.replace("\"" + name + "\"", ""));
    if(matcher.find()) {
        email = matcher.group().replaceAll("[<>]", "");
    }
    Je ne répondrai à aucune question technique par MP.

    Pensez aux Tutoriels et aux FAQs avant de poster ;) (pour le java il y a aussi JavaSearch), n'oubliez pas non plus la fonction Rechercher.
    Enfin, quand une solution a été trouvée à votre problème
    pensez au tag :resolu:

    Cours Dvp : http://ydisanto.developpez.com
    Blog : http://yann-disanto.blogspot.com/
    Page perso : http://yann-disanto.fr

  6. #6
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,

    Tu peux utiliser cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    	String str = "\"nom \\\"prenom\\\"\" <email@email.com>";
     
    	Pattern pattern = Pattern.compile( "\"(.*?)(?<!\\\\)\" <(.*?)>" );
    	Matcher matcher = pattern.matcher(str);
     
    	if (matcher.matches()) {
    		System.out.println("Nom   : " + matcher.group(1) );
    		System.out.println("Email : " + matcher.group(2) );
    	}
    Explication : \"(.*?)(?<!\\\\)\" <(.*?)>

    • \"(.*?) : un quote, suivi de n'importe quel caractère zéro ou plusieurs fois. Le *? permet de faire une recherche "reluctante", c'est à dire que c'est la plus petite chaine trouvé qui sera prise (par rapport au premier caractères qui suit)
    • (?<!\\\\)\" : La quote de fin, qui ne doit pas être précédé par un \ (quatruplé pour les raisons expliqué ici : Pourquoi dois-je doubler/quadrupler le caractère anti-slash ('\') ?).
    • <(.*?)> : Enfin l'adresse email...



    a++

Discussions similaires

  1. Réponses: 0
    Dernier message: 20/04/2011, 15h51
  2. [Regex] Comment gérer les parenthèses ?
    Par davcha dans le forum Framework .NET
    Réponses: 7
    Dernier message: 27/03/2006, 14h28
  3. Comment gérer les valeur Nulles dans une requête ?
    Par sondo dans le forum Bases de données
    Réponses: 3
    Dernier message: 16/03/2005, 11h02
  4. Comment gérer les espaces blancs?
    Par Lambo dans le forum XML/XSL et SOAP
    Réponses: 10
    Dernier message: 16/05/2003, 09h44

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