2 votes

Python3 - Générer une chaîne correspondant à plusieurs regex, sans les modifier

Je voudrais générer une chaîne correspondant à mes regex en utilisant Python 3. Pour cela, j'utilise une pratique bibliothèque appelée rstr.

Mes regex :

  • ^[abc]+.
  • [a-z]+

Ma tâche :

Je dois trouver un moyen générique de créer une chaîne qui correspondrait à mes deux regex.

Ce que je ne peux pas faire :

Modifier les deux regex ou les fusionner de quelque manière que ce soit. Je considère cela comme une solution inefficace, surtout dans le cas de regex incompatibles :

import re
import rstr

regex1 = re.compile(r'^[abc]+.')
regex2 = re.compile(r'[a-z]+')

for index in range(0, 1000):
  generated_string = rstr.xeger(regex1)
  if re.fullmatch(regex2, generated_string):
    break;
else:
  raise Exception('Les regex sont probablement incompatibles.')

print('La chaîne correspondant aux deux regex est : {}'.format(generated_string))

Y a-t-il une solution de contournement ou une bibliothèque magique qui peut gérer cela ? Toute aide est appréciée.

Questions qui semblent similaires, mais qui ne sont pas utiles :

L'auteur possède déjà la chaîne, qu'il veut simplement vérifier contre plusieurs regex de la manière la plus élégante. Dans mon cas, nous devons générer une chaîne de manière intelligente qui correspondrait aux regex.

1voto

MacHala Points 465

Si vous souhaitez vraiment une approche générique, vous ne pouvez pas vraiment utiliser une approche de force brute.

Ce que vous cherchez est de créer une sorte de représentation des expressions régulières (comme le fait rstr en appelant sre_parse.py) et ensuite d'appeler un solveur SMT pour satisfaire ces deux critères.

Pour Haskell, il existe https://github.com/audreyt/regex-genex qui utilise le solveur SMT Yices pour faire exactement cela, mais je doute qu'il y ait quelque chose de similaire pour Python. Si j'étais vous, je prendrais mon courage à deux mains et je l'appellerais en tant que programme externe depuis votre programme Python.

0voto

SanRyu Points 211

Je ne sais pas s'il y a quelque chose qui pourrait répondre à vos besoins de façon plus fluide. Mais je le ferais quelque chose comme (comme vous l'avez déjà fait):

  1. Créez un objet Regex avec la fonction re.compile().
  2. Générer une chaîne basée sur le 1er regex.
  3. Passez la chaîne que vous avez obtenue dans le 2ème objet regex en utilisant la méthode search().
  4. Si cela passe... vous avez terminé, la chaîne a passé les deux regex.

Peut-être pouvez-vous créer une fonction et passer les deux regex comme paramètres et tester "2 par 2" en utilisant la même logique.

Et ensuite, si vous avez 8 regex à matcher... Il suffit de faire:

call(regex1, regex2)
call(regex2, regex3)
call(regex4, regex5)
...

0voto

Fusion Points 996

J'ai résolu cela en utilisant une petite approche alternative. Remarquez que le deuxième regex est essentiellement une assurance pour que seules des lettres minuscules soient générées dans notre nouvelle chaîne.

J'ai utilisé le package python de Google sre_yield qui permet une limitation des caractères. Le package est également disponible sur PyPi. Mon code :

import sre_yield
import string

sre_yield.AllStrings(r'^[abc]+.', charset=string.ascii_lowercase)[0]
# retourne `aa`

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