Страницы

Поиск по вопросам

воскресенье, 7 апреля 2019 г.

Как в питоне сгенерировать все возможные строки, соответствующие регулярному выражению?

Есть некое регулярное выражение, например, "[a-z][0-9]{3}|[a-z]{3}". Как получить список всех возможных строк, соответствующих этому выражению? Примерно такой: ['a781', 'b000', 'c476', 'u132', 'd997', 'exe', 'use' и т.д.]


Ответ

Кроме самых простых случаев (без *+), кол-во строк, соотвествующих заданному регулярному выражению, может быть бесконечно.
Обратить регулярное выражение достаточно легко, например, re модуль позволяет получить регулярное выражение в виде дерева, обходя которое можно cгенерировать подходящую строку
import re from pprint import pprint
regex = "[a-z][0-9]{3}|[a-z]{3}" pprint(re.sre_parse.parse(regex).data)
Результат:
[('branch', (None, [[('in', [('range', (97, 122))]), ('max_repeat', (3, 3, [('in', [('range', (48, 57))])]))], [('max_repeat', (3, 3, [('in', [('range', (97, 122))])]))]]))]
bjmc написал rstr.xeger функцию, которая возвращает (одну, любую) строку, удовлетворяющую заданному regex:
import rstr # $ pip install rstr
regex = "[a-z][0-9]{3}|[a-z]{3}" print(rstr.xeger(regex)) # print a single string that matches the regex # -> ycu
Paul McGuire (pyparsing) упомянул сайт Инвертер регулярных выражений, основанный на invRegex.py примере:
from itertools import islice from invRegex import invert # http://pyparsing.wikispaces.com/file/view/invRegex.py
regex = "[a-z][0-9]{3}|[a-z]{3}" print("
".join(islice(invert(regex), 10000))) # print < 10000 matching strings
Результат:
a000 a001 a002 a003 a004 a005 a006 a007 a008 a009 a010 a011 a012 a013 a014 a015 a016 a017 a018 a019 a020 a021 a022 a023 a024 ...
Примеры взяты из ответов к Reversing a regular expression in python

Комментариев нет:

Отправить комментарий