Forum Programmation.autre Mini parser

Posté par  (site web personnel) .
Étiquettes : aucune
0
30
août
2004
Bonjour,
toujours dans ma periode regexp, j'ai aujourd'hui un nouveau problème surement très bête :
soit un fichier type :

bla bla
blou blou

Je souhaite faire une regexp me permettant d'afficher par exemple :

2 propriétés trouvées :
item1=bla bla
item2=bou blou

Mais je n'arrive pas a faire une regexp universelle détectant que la balise de fin est la meme que la balise d'ouverture


Quelqu'un peut il m'aiguiller ?
Merci
  • # Mince

    Posté par  (site web personnel) . Évalué à 1.

    Mes balises ont été mangées...
    le fichier est de la forme


    '<item1'> bla bla '</item1'>
    '<item2'> blou blou '</item2'>
    • [^] # Re: Mince

      Posté par  (site web personnel) . Évalué à 1.

      Toujours dans un soucis de clarté, a l'heure actuelle j'ai trouvé une solution assez simple :
      (<)(.*)(>)(.*)(</.*)

      Mais avec une telle methode, rien n'empeche de mettre une balise de fin correspondante a celle du début, et c'est là tout le problème.

      ps: les parenthèses partout c'est pour mieux traiter le résultats des matchs (je n'utilise que le groupe 2 et 4 au final)
      • [^] # Re: Mince

        Posté par  . Évalué à 2.

        et avec les références arrières ?

        genre (<)(.*)(>)(.*)(</)\2(>)

        cf http://www.bribes.org/perl/docfr/perlretut.html#LDE2F09D8(...)
        • [^] # Re: Mince

          Posté par  . Évalué à 3.

          ceci dit j'ai fait le mouton, j'ai remis des parenthèses partout alors que c'était pas la peine
          avec juste ceci tu as tout ce que tu veux :

          <(.*)>(.*)</\1>
        • [^] # Re: Mince

          Posté par  . Évalué à 2.

          et pourquoi t'embeter à tout mémoriser ?
          <(.*)>(.*)</\1> marche bien aussi :

          [binarym@gco]:~% echo "\<item1\>blabla plop\</item1\>" |perl -e 'if(<> =~ /<(.*)>(.*)<\/\1>/){ print "$1 -> $2\n"; }'
          item1 -> blabla plop

          [binarym@gco]:~% echo "\<item1\>blabla plop\</item3\>" |perl -e 'if(<> =~ /<(.*)>(.*)<\/\1>/){ print "$1 -> $2\n"; }'
          • [^] # Re: Mince

            Posté par  . Évalué à 2.

            J'ai pas testé, je suis pas un pro des regexp, mais j'y pense alors je vous en fais part:

            Le ".*" est "greedy" et donc va matcher sur tous les caractères jusqu'en fin de fichier; après, si la regexp se rend compte qu'il lui manque un truc pour s'appliquer au texte fourni, comme le tag fermant, elle va reessayer en allant moins loin.

            Donc il serait peut-être plus efficace (d'un point de vue consommation de ressource) d'utiliser ".*?" ("minimal matching") pour le nom du tag et pour le texte entre les tags.

            Peut-être même que c'est nécessaire si jamais ton fichier peut réutiliser le même tag:
            <item1> toto </item1>
            <item2> plop </item2>
            <item1> coin </item1>
            va matcher "toto </item1> <item2> plop </item2> <item1> coin " avec ".*" et "toto" + "coin" avec ".*?"

            (ou pas, selon que tu configure le <> de perl pour traiter ligne par ligne, ou tout le fichier d'un coup)

            $ man perlre
            "The pattern really, really wants to succeed"
        • [^] # Re: Mince

          Posté par  (site web personnel) . Évalué à 1.

          Bah merci a vous, vous avez parfaitement répondu a ma question :)

          Je plussois activement
    • [^] # Suggestion

      Posté par  . Évalué à 1.

      Pourquoi ne pas mettre tout simplement <item> , avec autant de d'item qu'il faut ? Ca évite de parser avec fois des noms de balises différentes.
      A moins que l'ordre soit important que tu ait des cas comme item2 item1 item3 ...
  • # Ce n'est pas un boulot pour des regexps

    Posté par  . Évalué à 1.

    À quoi ça sert de se la péter XML, si ce n'est pas pour offrir toute la souplesse du XML de base, au moins ?
    Si XML est bienvenu : utiliser expat (le plus light) ou une autre API.
    Sinon si tu veux persévérer avec des regexps (ton exemple était juste une instance de problème de références arrières), certains moteurs de regexps offrent effectivement ces références arrières ; généralement sous la forme que l'on retrouve dans la partie remplacement : \1 \2 etc.
  • # Commentaire supprimé

    Posté par  . Évalué à 1.

    Ce commentaire a été supprimé par l’équipe de modération.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.