3 votes

Python, analyseur Regex complexe

Je cherche donc à analyser un code à l'aide d'expressions régulières et je me demande s'il existe un moyen plus simple de le faire que ce que j'ai fait jusqu'à présent. Je vais commencer par un exemple de chaîne de caractères à analyser :

T16F161A286161990200040000\r (Ce sont des données qui arrivent par un dispositif série)

Maintenant, je dois d'abord vérifier le code de confirmation, qui sont les 9 premiers caractères du code. Ils doivent être exactement T16F161A2 . Si ces 9 caractères correspondent exactement, je dois vérifier les 3 caractères suivants qui doivent être soit 861 o 37F .

Si ces 3 personnages sont 37F Je lui ai fait faire quelque chose que je dois encore coder, donc nous ne nous soucierons pas de ce résultat.

Cependant, si ces 3 personnages sont 861 J'ai besoin qu'il vérifie les 2 caractères qui suivent pour voir ce qu'ils sont. Ils peuvent être 11 , 14 , 60 , 61 , F0 , F1 o F2 . Chacun d'entre eux fait des choses différentes avec les données qui le précèdent.

Enfin, je dois passer en revue les personnages restants, en les associant tous les deux.

Pour illustrer comment cela fonctionne, voici le code que j'ai créé pour analyser la chaîne de caractères que j'ai postée ci-dessus :

import re

test_string = "T16F161A286161990200040000\r"

if re.match('^T16F161A2.*', test_string):
    print("Match: ", test_string)
    test_string = re.sub('^T16F161A2', '', test_string)
    if re.match('^861.*', test_string):
        print("Found '861': ", test_string)
        test_string = re.sub('^861', '', test_string)
        if re.match('^61.*', test_string):
            print("Found '61' : ", test_string)
            test_string = re.sub('^61', '', test_string)
            for i in range(6):
                if re.match('^[0-9A-F]{2}', test_string):
                    temp = re.match('^[0-9A-F]{2}', test_string).group()
                    print("Found Code: ", temp)
                test_string = re.sub('^[0-9A-F]{2}', '', test_string)

Maintenant, comme vous pouvez le voir dans ce code, après chaque étape, je suis en train d'utiliser re.sub() pour enlever la partie de la ficelle que je venais de chercher. Dans cette optique, ma question est la suivante :

Existe-t-il un moyen d'analyser la chaîne et de trouver les données dont j'ai besoin, tout en conservant la chaîne intacte ? Serait-ce plus ou moins efficace que ce que j'ai actuellement ?

0voto

dashiell Points 737

Peut-être quelque chose comme :

import re

regex = r'^T16F161A2(861|37f)(11|14|60|61|F0|F1|F2)(.{2})(.{2})(.{2})(.{2})(.{2})(.{2})$'
string = 'T16F161A286161990200040000'

print re.match(regex,string).groups()

Cela permet d'utiliser les groupes de capture et évite de devoir créer un tas de nouvelles chaînes.

0voto

Serge Ballesta Points 12850

El re ne sera pas aussi efficace que l'accès direct aux sous-chaînes, mais il pourrait vous éviter d'écrire (et de maintenir) quelques lignes de code. Mais si vous voulez l'utiliser, vous devez faire correspondre la chaîne de caractères dans son ensemble :

import re

test_string = "T16F161A286161990200040000\r"

rx = re.compile(r'T16F161A2(?:(?:(37F)(.*))|(?:(861)(11|14|60|61|F0|F1|F2)(.*)))\r')
m = rx.match(test_string)      # => 5 groups, first 2 if 37F, last 3 if 861

if m is None:                  # string does not match:
    ...
elif m.group(1) is None:       # 861 type
    subtype = m.group(4)       # extract subtype
    # and group remaining characters by pairs
    elts = [ m.group(5)[i:i+2] for i in range(0, len(m.group(5)), 2) ]
    ...                        # process that
else:                          # 37F type
    ...

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X