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

Python Discussion :

Utilisation des expressions régulières


Sujet :

Python

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 36
    Points : 25
    Points
    25
    Par défaut Utilisation des expressions régulières
    Bonjour.

    Sur une ligne de type complexe, j'essaie de décomposer en groupes de données parlantes.
    J'essaie avec les expressions régulières, mais pour l'instant ne parviens pas au résultat escompté.
    Un exemple valant mieux qu'un long discours :

    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
    import re
    line = '46.193.16.35 - hguelbeye [02/Nov/2017:00:59:35 +0100] "POST <a href="http://www.dalloz.fr:80/documentation/SessionHandler.svc/GetSessionLive?id=RECUEIL/IR/1996/0884&ctxt=0_YSR0MT1sZSBqdWdlIGV0IGFwcGxpY2F0aW9uIGRlIGxhIGxvaSBldHJhbmdlcmXCp3gkc2Y9cGFnZS1yZWNoZXJjaGU=&ctxtl=0_cyRwYWdlTnVtPTHCp3MkdHJpZGF0ZT1GYWxzZcKncyRzb3J0PcKncyRzbE5iUGFnPTIwwqdzJGlzYWJvPUZhbHNlwqdzJHBhZ2luZz1UcnVlwqdzJG9uZ2xldD3Cp3MkZnJlZXNjb3BlPUZhbHNlwqdzJHdvSVM9RmFsc2U=&nrf=0_TGlzdGU=" target="_blank">http://www.dalloz.fr:80/documentatio...nrf=0_TGlzdGU=</a> HTTP/1.1" 200 587'
     
    # Expression régulière pour les log. 
    # On est censé récupérer ip, login, datetime, url, path
    regex = "^(?P<ip>(?:[0-9]{1,3}\.){3}[0-9]{1,3}) - " \
                "(?P<login>[0-9a-zA-Z]*) .*" \
                "\[(?P<datetime>.*)\].*connect\?session=.*&url=" \
                "https?://w*\.?(?P<url>.[^/]*)/(?P<path>.*) HTTP/1.1.*"
     
    chain1 = re.compile(regex)
    match1 = chain1.match(line)
     
    if match1:
               url = match1.group("url")
               dt1 = match1.group("datetime")
               P_login = match1.group("login")
    Je n'arrive pas à comprendre pourquoi ça ne marche pas.
    Quelqu'un a une idée ?
    Une autre solution pour décomposer ce genre de ligne ?

    Merci de votre aide ;-)

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 273
    Points : 36 757
    Points
    36 757
    Par défaut
    Salut,

    Citation Envoyé par lylandra6 Voir le message
    Je n'arrive pas à comprendre pourquoi ça ne marche pas.
    Quelqu'un a une idée ?
    Si çà ne fonctionne pas, c'est parce que votre expression régulière est mal écrite. Et donc la vraie question est de comment la mettre au point. Dans votre cas, vous avez de la chance puisqu'elle est composée de plusieurs groupes qui "mangent" la ligne.
    Donc vous pouvez tester si çà attrape bien IP tout seul, puis IP suivi de LOGIN, puis... lorsque vous trouvez un problème, vous vous concentrez la dessus avec une sous-chaîne à parser et un bout de la regexp.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2004
    Messages
    253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : Avril 2004
    Messages : 253
    Points : 446
    Points
    446
    Par défaut
    Bonjour,

    La ligne donnée ne matche pas l'expression régulière; c'est pour ça qu'il n'y a aucun résultat.
    Il n'y a pas de 'connect' ou de 'session'.
    Comme l'a dit wiztricks, le mieux est de procéder par étapes: tester la récupération de l'ip, puis du login, puis....

    Lorsque ça matche, tu peux récupérer tous les groupes et la valeur correspondante dans un dictionnaire avec: match1.groupdict()

    Pour ma part, j'obtiens un résultat pas trop mal (à vérifier avec ce qui est attendu) avec l'expression suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    regex = "(?P<ip>(?:[0-9]{1,3}\.){3}[0-9]{1,3}) - " \
            "(?P<login>[0-9a-zA-Z]*) .*" \
            "\[(?P<datetime>.*)\]" \
            ".*https?://w*\.?(?P<url>.[^/]*)/(?P<path>.*) HTTP/1.1.*"
    Il est agréable d'avoir le choix. La difficulté est alors de faire le bon (ou le moins pire).

  4. #4
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 461
    Points : 9 248
    Points
    9 248
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Voilà ce que j'ai trouvé (Python 3):

    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
    import re
     
    line = '46.193.16.35 - hguelbeye [02/Nov/2017:00:59:35 +0100] "POST <a href="http://www.dalloz.fr:80/documentation/SessionHandler.svc/GetSessionLive?id=RECUEIL/IR/1996/0884&ctxt=0_YSR0MT1sZSBqdWdlIGV0IGFwcGxpY2F0aW9uIGRlIGxhIGxvaSBldHJhbmdlcmXCp3gkc2Y9cGFnZS1yZWNoZXJjaGU=&ctxtl=0_cyRwYWdlTnVtPTHCp3MkdHJpZGF0ZT1GYWxzZcKncyRzb3J0PcKncyRzbE5iUGFnPTIwwqdzJGlzYWJvPUZhbHNlwqdzJHBhZ2luZz1UcnVlwqdzJG9uZ2xldD3Cp3MkZnJlZXNjb3BlPUZhbHNlwqdzJHdvSVM9RmFsc2U=&nrf=0_TGlzdGU=" target="_blank">http://www.dalloz.fr:80/documentatio...nrf=0_TGlzdGU=</a> HTTP/1.1" 200 587'
     
    motif = r"^(?P<ip>[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}) - (?P<login>[a-zA-Z][a-zA-Z0-9]*) (?P<datetime>\[.*\]).*(?P<url>http[s]?://.*HTTP/1.1)"
     
    regex = re.compile(motif)
    match = regex.search(line)
     
    if match!=None:
     
        ip = match.group("ip")
        print("ip:", ip)
     
        login = match.group("login")
        print("login:", login)
     
        datetime = match.group("datetime")
        print("datetime:", datetime)
     
        url = match.group("url")
        print("url:", url)
     
    else:
        print("Pas trouvé!")
    Ce qui affiche:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    ip: 46.193.16.35
    login: hguelbeye
    datetime: [02/Nov/2017:00:59:35 +0100]
    url: http://www.dalloz.fr:80/documentatio...nrf=0_TGlzdGU=</a> HTTP/1.1
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  5. #5
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    salut,

    ce type de ligne est extraite d'un log de serveur web (nginx), le format de la ligne est spécifié dans la configuration du serveur directement

    ce qu'on récupère en dernier champs n'est pas une url, c'est la requête du client, ici dans l'exemple c'est une requête POST avec des données qui contiennent des guillemets ", c'est d'autant plus piégeux, derrière on trouve le code HTTP renvoyé suivi en général du nombre d'octets de la réponse ou - si aucun octet n'est renvoyé, le login aussi peut éventuellement être -.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    >>> pattern = r'^(?P<ip>(?:\d+\.){3}\d+) (?:-|.+?) (?P<login>-|.+?) \[(?P<datetime>.{26})\] \"(?P<req>.+)\" (?P<code>\d+) (?P<ansbytes>-|\d+)$'
    >>> s = '46.193.16.35 - hguelbeye [02/Nov/2017:00:59:35 +0100] "POST machin "truc" bidule "pouet" coincoin" 200 587'
    >>> reg = re.compile(pattern)
    >>> reg.search(s)['req']
    'POST machin "truc" bidule "pouet" coincoin'
    le champ req a beau être délimité par des guillemets, la regex prend bien l'intégralité de son contenu

    du coup si on reprend l'exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >>> s = '46.193.16.35 - hguelbeye [02/Nov/2017:00:59:35 +0100] "POST <a href="http://www.dalloz.fr:80/documentation/SessionHandler.svc/GetSessionLive?id=RECUEIL/IR/1996/0884&ctxt=0_YSR0MT1sZSBqdWdlIGV0IGFwcGxpY2F0aW9uIGRlIGxhIGxvaSBldHJhbmdlcmXCp3gkc2Y9cGFnZS1yZWNoZXJjaGU=&ctxtl=0_cyRwYWdlTnVtPTHCp3MkdHJpZGF0ZT1GYWxzZcKncyRzb3J0PcKncyRzbE5iUGFnPTIwwqdzJGlzYWJvPUZhbHNlwqdzJHBhZ2luZz1UcnVlwqdzJG9uZ2xldD3Cp3MkZnJlZXNjb3BlPUZhbHNlwqdzJHdvSVM9RmFsc2U=&nrf=0_TGlzdGU=" target="_blank">http://www.dalloz.fr:80/documentatio...nrf=0_TGlzdGU=</a> HTTP/1.1" 200 587'
    >>> reg.search(s)['req']
    'POST <a href="http://www.dalloz.fr:80/documentation/SessionHandler.svc/GetSessionLive?id=RECUEIL/IR/1996/0884&ctxt=0_YSR0MT1sZSBqdWdlIGV0IGFwcGxpY2F0aW9uIGRlIGxhIGxvaSBldHJhbmdlcmXCp3gkc2Y9cGFnZS1yZWNoZXJjaGU=&ctxtl=0_cyRwYWdlTnVtPTHCp3MkdHJpZGF0ZT1GYWxzZcKncyRzb3J0PcKncyRzbE5iUGFnPTIwwqdzJGlzYWJvPUZhbHNlwqdzJHBhZ2luZz1UcnVlwqdzJG9uZ2xldD3Cp3MkZnJlZXNjb3BlPUZhbHNlwqdzJHdvSVM9RmFsc2U=&nrf=0_TGlzdGU=" target="_blank">http://www.dalloz.fr:80/documentatio...nrf=0_TGlzdGU=</a> HTTP/1.1'
    le champ req se compose de la méthode HTTP (GET, POST, HEAD, OPTION..) suivi d'un espace puis des données (lesquelles proviennent directement de l'utilisateur) suivi d'un espace puis de la version HTTP et se termine par un guillemet :
    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
    >>> pattern =   r'^'                             \
    ...             r'(?P<ip>(?:\d+\.){3}\d+) - '    \
    ...             r'(?P<login>-|.+?) '             \
    ...             r'\[(?P<datetime>.{26})\] '      \
    ...             r'\"(?P<method>GET|POST) '       \
    ...             r'(?P<datas>.+) '                \
    ...             r'(?P<version>HTTP/\d\.\d)\" '   \
    ...             r'(?P<code>\d+) '                \
    ...             r'(?P<bytesent>-|\d+)'           \
    ...             r'$'
    >>> reg = re.compile(pattern)
    >>> reg.search(s)['method']
    'POST'
    >>> reg.search(s)['version']
    'HTTP/1.1'
    >>> reg.search(s)['datas']
    '<a href="http://www.dalloz.fr:80/documentation/SessionHandler.svc/GetSessionLive?id=RECUEIL/IR/1996/0884&ctxt=0_YSR0MT1sZSBqdWdlIGV0IGFwcGxpY2F0aW9uIGRlIGxhIGxvaSBldHJhbmdlcmXCp3gkc2Y9cGFnZS1yZWNoZXJjaGU=&ctxtl=0_cyRwYWdlTnVtPTHCp3MkdHJpZGF0ZT1GYWxzZcKncyRzb3J0PcKncyRzbE5iUGFnPTIwwqdzJGlzYWJvPUZhbHNlwqdzJHBhZ2luZz1UcnVlwqdzJG9uZ2xldD3Cp3MkZnJlZXNjb3BlPUZhbHNlwqdzJHdvSVM9RmFsc2U=&nrf=0_TGlzdGU=" target="_blank">http://www.dalloz.fr:80/documentatio...nrf=0_TGlzdGU=</a>'
    on voit clairement que les données en question c'est du HTML, à ce stade il conviendrait donc de dégainer BeautifulSoup ou autre pour récupérer ce qu'on souhaite.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    >>> from bs4 import BeautifulSoup
    >>> soup = BeautifulSoup(reg.search(s)['datas'], 'html.parser')
    >>> soup.text
    'http://www.dalloz.fr:80/documentatio...nrf=0_TGlzdGU='

Discussions similaires

  1. Réponses: 2
    Dernier message: 04/10/2010, 21h00
  2. Réponses: 2
    Dernier message: 26/11/2008, 09h28
  3. Réponses: 2
    Dernier message: 08/05/2008, 20h41
  4. Réponses: 6
    Dernier message: 30/05/2007, 17h31
  5. Réponses: 5
    Dernier message: 20/09/2006, 13h16

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