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

Shell et commandes GNU Discussion :

sed & regex: matcher 2 champs à la fois


Sujet :

Shell et commandes GNU

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre régulier
    Homme Profil pro
    chercheur
    Inscrit en
    Janvier 2017
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : chercheur

    Informations forums :
    Inscription : Janvier 2017
    Messages : 8
    Par défaut sed & regex: matcher 2 champs à la fois
    Je cherche a extraire noms de fichier image + titres dans un gros fichier html.
    ( Ok ça serait faisable en autre chose que sed, mais j'y étais presque et ça m'interesse de comprendre anyway :-) )

    voici l'expression à laquelle je suis parvenu, sur une courte chaine d'exemple, mais ça ne marche pas:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    echo '(path/yac5cxfjm1.png)"></span><xxx><yyy>le titre</span>' | sed 's#/\([0-9a-z]*\).png)"></span>\([!>]*\)>\([!>]*\)>\([!<]*\)#@ FILE:\1 TITLE:\4/a%\n#g'
    visiblement le probleme se situe au premier '>':
    s#/\([0-9a-z]*\).png)"></span>\([!>]*\) matche mon exemple,
    mais pas
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    s#/\([0-9a-z]*\).png)"></span>\([!>]*\)>
    une idee du soucis ?
    (NB: c'est pas une question d'echappement de ! et > , j'ai déjà testé)
    NB: j'en suis venu a matcher explicitement chaque <...> entre mes 2 champs visés (nom et titre), parceque \(.*\) essayé auparavant semble faire un match maximaliste et non minimaliste.

    merci !

  2. #2
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 673
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 673
    Par défaut
    BONJOUR !

    empiriquement j'en arrive à ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ echo '(path/yac5cxfjm1.png)"></span><xxx><yyy>le titre</span>' | sed 's/.*\/\([^.]*\).png.*>\(.*\)<\/.*/\1 -- \2/'
    yac5cxfjm1 -- le titre
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  3. #3
    Membre régulier
    Homme Profil pro
    chercheur
    Inscrit en
    Janvier 2017
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : chercheur

    Informations forums :
    Inscription : Janvier 2017
    Messages : 8
    Par défaut
    Citation Envoyé par N_BaH Voir le message
    empiriquement j'en arrive à ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ echo '(path/yac5cxfjm1.png)"></span><xxx><yyy>le titre</span>' | sed 's/.*\/\([^.]*\).png.*>\(.*\)<\/.*/\1 -- \2/'
    yac5cxfjm1 -- le titre
    Certes, mais comme je disais, \(.*\) a une facheuse tendance a matcher a maxima, c'est a dire avec tout le reste du bloc.
    Donc dans le vrai contexte ou je dois reconnaitre toute une serie de nom + titre, ça ne marche plus :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    echo '(path/file1.png)"></span><xxx><yyy>le titre1</span><zzz><(path/file2.png)"></span><xxx><yyy>le titre2</span>' | sed 's/.*\/\([^.]*\).png.*>\(.*\)<\/.*/\1 -- \2/'g
    par ailleurs là j'ai simplifié les balises intermédiaires, mieux vaut donc vraiment reconnaire le fichier comme \/\([0-9a-z]*\).png pour matcher specifiquement.
    Mais ça ne change rien au 1er soucis avec \(.*\) . C'est bien pour ça que j'en suis venu spécifiquement a reconnaitre les 2 balises intermédiaires, a coup de "non '>'" puis '>'.

    Ce serait utile qu'on sache ce que tu veux obtenir.
    un site tiers a oublié de prévoir qu'on puisse vouloir faire des backup de nos fiches, ou en donner la liste des liens sur nos blogs. Mais il y a un menu généré dynamiquement qui les affiche. En sauvant le html (un gros bloc bien moche), on arrive facilement a reconnaitre les champs utiles (pour chaque entree de la liste, path vers la miniature de la fiche, reutilisable pour indexer la fiche elle meme, et titre). Ok, vouloir faire ça avec sed c'est bourrin par rapport a un parseur xml, mais j'y suis facilement arrivé sans la partie titre, et là je butte... et j'aimerais comprendre l'erreur conceptuelle, anyway :-)

  4. #4
    Expert confirmé Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 986
    Par défaut
    En fait, tu te trompes sur le signe de négation d'une classe de caractère qui n'est pas le point d'exclamation mais l'accent circonflexe.

  5. #5
    Membre régulier
    Homme Profil pro
    chercheur
    Inscrit en
    Janvier 2017
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : chercheur

    Informations forums :
    Inscription : Janvier 2017
    Messages : 8
    Par défaut
    Citation Envoyé par CosmoKnacki Voir le message
    En fait, tu te trompes sur le signe de négation d'une classe de caractère qui n'est pas le point d'exclamation mais l'accent circonflexe.
    euh, oui (damned !!! ).

    mais j'ai toujours le probleme que ça n'embraye pas sur le second nom+titre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    echo '(path/yac5cxfjm1.png)"></span><xxx><yyy>le titre</span>' | sed 's#/\([0-9a-z]*\).png)"></span>\([^>]*\)>\([^>]*\)>\([^<]*\)#@ FILE:\1 TITLE:\4/a%\n#g'
    matche bien le premier set, mais appliqué à des données plus longues
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    echo '(path/nom1.png)"></span><xxx><yyy>le titre1</span><zzz>(path/nom2.png)"></span><xxx><yyy>le titre2</span><zzz>' | sed 's#/\([0-9a-z]*\).png ) "></span>\([^>]*\)>\([^>]*\)>\([^<]*\)#@ FILE:\1 TITLE:\4/a%\n#g'
    ça ne match plus rien du tout, ni le 1er ni le 2d set nom+titre.

  6. #6
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 673
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 673
    Par défaut
    les données sont tronquées, tu devrais nous donner les vraies données (en remplaçant les informations personnelles, bien sûr), et en respectant le formatage.

    tout semble être sur une seule ligne, sed (pour le peu que je sache) ne va pas pouvoir réutiliser les mêmes références arrières pour chaque motif "fichier" et "titre", même avec le paramètre g.

    mais ce serait sûrement plus raisonnable, puisque c'est du XML, comme tu l'as dit, d'utiliser un parseur XML.
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

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

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