Problme d'expression régulière

Fermé
frip - 6 juil. 2011 à 13:00
KX Messages postés 16752 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 août 2024 - 7 juil. 2011 à 15:06
Bonjour,

J'aimerais à l'aide d'une expression régulière capturé certains blocs de commentaire JAVA. En particulier, j'aimerais extraire le tag Javadoc et la valeur qui suit. Sachant qu'une valeur peut être sur plusieurs ligne, il faut détecter la fin d'une valeur par le commencement d'un nouveau tag(@) ou la fin d'un commentaire (*/).

Donc en gros j'ai un texte de cette forme:
/**
 * This takes the string that is passed in, and "auto-links" it, it turns email addresses into hyperlinks, and also
 * turns things that looks like URLs into hyperlinks as well.
 * @author Fabrizio Giustina
 * @version $Revision: 1081 $ ($Author: fgiust $)
 */


Et je voudrais récupérer:
Matched String : @author Fabrizio Giustina (puis les différents groupe)
groupe 1 : @author
groupe 2 : Fabrizio Giustina *

(pareil pour le deuxième tag)

Seulement je n'arrive pas à trouver la bonne Regex, la meilleur que je trouve me renvoie ce que je veux plus un troisieme groupe vide correspondant a l'espace entre l'etoile(*) et le début du deuxième tag (@). Je ne comprend pas pourquoi.

voici ma regex: (@\w+)(([^@|\/])*)

Merci d'avance pour ceux qui prendront le temps de m'aider,
Cordialement,
Frip

2 réponses

Je sais pas si ça peu aider, mais voici un générateur de regex bien pratique:
http://txt2re.com/index-java.php3
0
Merci, ça à l'air d'être une application intéressante. Mais je crois que ça ne peut pas être utilisé pour généraliser mon problème.
0
Et si tu commence par une fonction qui enlève les étoiles de ta chaine ?
0
En fait je dois faire un truc le plus générique possible. Donc, je ne peut pas toucher au texte avant. Je dois récupérer ce dont j'ai besoin à partir d'une expression régulière. Et en l'occurence, ce dont j'ai besoin c'est le TAG(@tag) et la valeur qui suit. donc deux groupes. Et la difficulité ici, c'est que la valeur peut être sur plusieurs ligne et qu'elle se termine soit par @ ou */
0
Celle là: (@\w+)(([^@|\/|\*])*) ?
0
Non. Cela enlève bien l'espace après l'étoile vu que la regex exclus l'étoile mais cela crée un nouveau groupe vide en prendant celui après Giustina et l'étoile.
Mais en plus, je ne veux pas exclure l'étoile dans la requete puisqu'un commentaire pourrait bien être comme le suivant :
/*...
 * turns things that looks like URLs into hyperlinks as well.
 * @author Fabrizio Giustina
 *  suite de la valeur
 * @version $Revision: 1081 $ ($Author: fgiust $)
 */


et dans ce cas il faudrait récuperer
@author Fabrizio Giustina
* suite de la valeur
*
qui contient bien des étoile.
Merci de me proposer ton aide!
0
KX Messages postés 16752 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 août 2024 3 019
6 juil. 2011 à 17:28
Regarde ce code, je pense qu'il devrait répondre à ton problème.
Je n'aime pas trop utiliser une seule expression régulière pour gérer tous les cas, je trouve cela absurde vu tout ce que l'on peut faire avec Java.
J'ai donc "caché" les expressions régulières derrière l'utilisation de Scanner.

Tu te retrouves avec une méthode qui calcul (efficacement) en une seule fois toutes les valeurs que tu peux extraire de ta chaîne de caractères.
Regarde ce que fais le main, tu vas voir c'est assez simple à utiliser.

import java.util.HashMap; 
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;

class Table extends HashMap<String,List<String>>
{
    private static final long serialVersionUID = 1L;
}

public class Test 
{ 
    public static Table extract(String comment)
    {
        Table t = new Table();
        String key="";
        List<String> value = null;
        
        Scanner sc = new Scanner(comment.substring(comment.indexOf("/**")+3, comment.indexOf("*/")-1));
        sc.useDelimiter("[\\s]*[*]+[\\s]*");
        
        while (sc.hasNext())
        {
            String str = sc.next();
            
            if (str.startsWith("@"))
            {
                if (value!=null)
                    t.put(key, value);
                value=new LinkedList<String>();
                
                int n = str.indexOf(" ");
                key=str.substring(1,n);
                str=str.substring(n+1);
            }
            
            if (value==null)
                value=new LinkedList<String>();
            value.add(str);
        }
        
        sc.close();
        t.put(key,value);
        return t;
    }

    public static void main(String args[])
    {
        String exemple =
             "/**\n"
            +" * This takes the string that is passed in, and \"auto-links\" it, it turns email addresses into hyperlinks, and also\n"
            +" * turns things that looks like URLs into hyperlinks as well.\n"
            +" * @author Fabrizio Giustina\n"
            +" * @version $Revision: 1081 $ ($Author: fgiust $)\n"
            +" */\n";
        
        Table t = extract(exemple);
        
        for (String s : t.get(""))
            System.out.println("1) "+s);
        
        for (String s : t.get("author"))
            System.out.println("2) "+s);
        
        for (String s : t.get("version"))
            System.out.println("3) "+s);
   }
}
0
Merci beaucoup pour l'aide proposer. En fait, je dois faire une application qui charge dans un fichier des expression régulière correspondant à des blocs que l'utilisateur voudrais extraire dans des commentaires. Et ce, dans différents langages, pas seulement en Java. Il faut que mon application soit la plus générique possible, donc je pense, sans traitement Java pour s'occuper a nettoyer le code derrière (comme s'occuper des étoiles). Je pense que la grosse limite de ce genre d'application du goût c'est la puissance des RegeX. Je ne sais pas si je peux faire ce que je veux en une seule expression régulière. Si ce n'est pas le cas je mettrais une option au chargement du fichier qui indiquera si oui ou non je prend en compte les groupes vides cela restera générique..

Merci encore!
0
KX Messages postés 16752 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 août 2024 3 019
7 juil. 2011 à 15:06
Tu peux toujours essayer d'établir un automate déterministe pour chacun de tes problèmes et en déduire une expression régulière "générique" que tu adapteras à ton langage de programmation.
Evidemment à partir d'un automate, l'expression régulière risque d'être longue... mais elle sera sûre ;-)
0