Partager
Affiche les résultats de 1 à 1 sur 1

Sujet : [Python] IRC Parser

  1. #1
    Inscrit
    September 2010
    Lieu
    Lorraine (France)
    Messages
    19
    Remerciements
    4
    Remercié(e) 5 fois dans 4 messages
    Pouvoir de réputation
    0

    [Python] IRC Parser

    Bonjour,

    Je voudrais partager avec vous une expression régulière que j'ai fait il y a quelque temps pour parcourir les messages IRC. Ça peut être intéressant lorsqu'on veux faire un client ou un bot IRC par exemple.

    L'expression régulière en question est un monstre de 3km de long, mais vous pouvez facilement la décortiquer en utilisant la représentation BNF présente dans le RFC IRC qui décrit le format des messages IRC et dont je me suis -en parti- servi pour faire l'expression régulière:

    Code:
    ^(:((([][}{\\^`_a-zA-Z][][}{\\^`\w-]*)|([^\0 \r\[email protected]]+))(![^\0 \r\[email protected]]+)?(@[^\0 \r\n]+)?) +)?([a-zA-Z]+|\d\d\d)((( +[^: \0\r\n][^ \0\r\n]*)*) +:([^\r\n]*))\r\n$
    Le format des messages est présent sur le lien suivant:
    http://abcdrfc.free.fr/rfc-vf/rfc1459.html#231

    Si on prend l'exemple du message IRC suivant:

    :[email protected] PRIVMSG ##jmct :Salut all

    Le résultat sera décomposer selon l'expression régulière en quelque chose comme suite:

    ':[email protected] ' ==> :PrefixSpaces
    '[email protected]' ==> Prefix
    'ShNaYkHs' ==> Nick/ServerName
    'ShNaYkHs' ==> Nickname
    None ==> Servername
    '!n=ShNaYkHs' ==> !Username
    '@41.209.159.158' ==> @Host
    'PRIVMSG' ==> Commande
    ' ##jmct :Salut' ==> Params
    ' ##jmct' ==> SpacesArguments
    ' ##jmct' ==> SpacesLastArgument
    'Salut all' ==> Content

    Il faut savoir que les messages IRC sont délimité à la fin par CR LF (c'est à dire, fin de ligne \r\n) et l'expression régulière respecte ceci (fin du message indiqué par \r\n) donc si on reçois une chaine de caractères en vrac (contenant plusieurs messages IRC à la fois) de la part d'un serveur IRC, on dois spliter (diviser) la chaine en sous chaines se terminant par \r\n

    Je vous donne si dessous un exemple d'un bot IRC simplifié qui utilise cette expression régulière:

    Code:
    import socket
    import re
    
    HOST = "irc.exempleServeurIrc.org"
    PORT = 6667
    CHANNEL = "#unChanIrc"
    BOTNICK = "ShNaYkHsBot"
    BOTUSER = "ShNaYkHsBot"
    
    last_sous_data = ""
    
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect( ( HOST, PORT ) )
    sock.send('NICK ' + BOTNICK + '\r\n')
    sock.send('USER ' + BOTUSER + ' foo bar :' + BOTUSER + '\r\n')
    sock.send('JOIN ' + CHANNEL + '\r\n')
    
    while True:
        data = sock.recv(1024)
        if len(data) > 0:
            data = last_sous_data + data
            sous_data = data.split("\r\n")
            if sous_data[-1] == '':
                last_sous_data = ""
                sous_data = sous_data[0:-1]
                sous_data = [elem + "\r\n" for elem in sous_data]
            else:
                last_sous_data = sous_data[-1]
                sous_data = [elem + "\r\n" for elem in sous_data[0:-1]]
                
            for s_data in sous_data:
                nicknamePattern = re.compile(r'^(:((([][}{\\^`_a-zA-Z][][}{\\^`\w-]*)|([^\0 \r\[email protected]]+))(![^\0 \r\[email protected]]+)?(@[^\0 \r\n]+)?) +)?([a-zA-Z]+|\d\d\d)((( +[^: \0\r\n][^ \0\r\n]*)*) +:([^\r\n]*))\r\n$')
                matches = nicknamePattern.search(s_data)
                if matches == None:
                    command = ""
                    # print "DEBUG: ************* Does not matches ! *******************"
                    # print "Info Debug: <" + s_data + ">"
                else:
                    li_parse = matches.groups()
                    command = li_parse[7].upper()
                    # print matches.groups()
                    # print "================= "+str(len(s_data))+" ======================\n"
                    
                    if command == 'JOIN':
                        nickName = li_parse[2]
                        channelName = li_parse[11]
                        if nickName == BOTNICK:
                            sock.send('PRIVMSG '+CHANNEL+' :Salut tout le monde.\r\n')
                        else:
                            sock.send('PRIVMSG '+CHANNEL+' :Bienvenue '+nickName+'.\r\n')
                    # etc IRC commands ...
    Toutefois, il peut y avoir une incompatibilité avec quelque messages de certains serveurs IRC, ceci peut être due au spécifications particulières des serveurs concernés (message DEBUG en commentaire dans le code source).

    Salutations.
    Dernière édition par ShNaYkHs; 23/09/2010 à 02h36 Raison: balises code
    Man scherzt nicht mit der ShNaYkHs (oder nicht)

  2. [Les 2 membres suivants remercient ShNaYkHs pour cet excellent message :


  3. # ADS
    Inscrit
    Toujours
    Lieu
    Monde des annonces
    Messages
    Plusieurs






     

Sujets similaires

  1. Python African Tour Alger
    Par ychaouche dans le forum Programmation
    Réponses: 10
    Dernier message: 07/02/2013, 08h47
  2. Réponses: 13
    Dernier message: 03/08/2012, 00h06
  3. Réponses: 0
    Dernier message: 23/07/2012, 04h29
  4. Un Python Qui Parle
    Par abitaf dans le forum Vannes
    Réponses: 2
    Dernier message: 19/02/2011, 08h08

Tags pour ce sujet

Règles des messages

  • Vous ne pouvez pas créer de sujets
  • Vous ne pouvez pas répondre aux sujets
  • Vous ne pouvez pas importer de fichiers joints
  • Vous ne pouvez pas modifier vos messages
  •  
  • Les BB codes sont Activés
  • Les Smileys sont Activés
  • Le BB code [IMG] est Activé
  • Le code [VIDEO] est Activé
  • Le code HTML est Désactivé



Liens annexes