J'écris un analyseur Lisp en Python dans le cadre d'un projet de compilateur. Mon tokenizer fonctionne comme ceci :

def tokenize(filename):
    with open(filename, "r") as file:
        comment_free = remove_comments(file.read())
    return comment_free.replace("(", " ( ").replace(")", " ) ").split()

Les caractères Lisp sont un peu différents : le caractère a serait #\a, ( serait #\(, et cetera. Pour les caractères qui contiennent une parenthèse gauche ou droite, ils sont séparés à tort par le tokenizer en deux parties distinctes (#\ et ( ou )).

Je peux faire correspondre l'indicateur de caractère avec [^#\] et la parenthèse avec \(|\), mais comment puis-je créer un modèle qui vérifie si une partie du code ne commence pas par un indicateur de caractère et suit avec une gauche ou une droite parenthèse? Si je peux créer un tel modèle, je peux remplacer toutes ces instances par une parenthèse entourée d'espaces. Je pensais que ([^#\\])(\(|\))* fonctionnerait mais cela ne fonctionne pas dans tous les cas. Est-ce que quelqu'un qui maîtrise l'expression régulière sait comment résoudre ce problème ?

2
Caspian Ahlberg 9 nov. 2020 à 21:49

1 réponse

Meilleure réponse

comment créer un modèle qui vérifie si une partie du code ne commence pas par un indicateur de caractère et suit avec une parenthèse gauche ou droite ?

Vous pouvez utiliser un lookbehind négatif pour vérifier que l'indicateur n'est pas à gauche et faire correspondre ( ou ) en utilisant une classe de caractères au lieu d'une alternance.

(?<!#\\)[()]

Explication

  • (?<!#\\) Regard négatif, affirmez que ce qui est directement à gauche ne l'est pas #\
  • [()] Correspond à ( ou )

Démo Regex


Si l'indicateur est # ou \\, vous pouvez utiliser 2 classes de caractères :

(?<![#\\])[()]

Démo Regex

3
The fourth bird 9 nov. 2020 à 20:22