Хорошо, просто размышляю, но общий вопрос о генерации случайных входных данных, соответствующих регулярному выражению, звучит для меня выполнимо для достаточно смягченного определения случайного и достаточно точного определения регулярного выражения. Я имею в виду классическое формальное определение, которое допускает только () | * и буквы алфавита.
Регулярные выражения могут быть сопоставлены с формальными машинами, называемыми конечными автоматами . Такая машина представляет собой ориентированный граф с конкретным узлом, называемым конечным состоянием, узлом, называемым начальным состоянием, и буквой из алфавита на каждом ребре. Слово принимается регулярным выражением, если можно начинать с начального состояния и проходить по одному ребру, помеченному каждым символом, через график и заканчиваться в конечном состоянии.
Можно построить график, затем начать с конечного состояния и пересекать случайные ребра назад, отслеживая путь. В стандартной конструкции каждый узел в графе доступен из начального состояния, поэтому вам не нужно беспокоиться о том, что вы можете исправить ошибку и откатиться назад. Если вы достигнете начального состояния, остановитесь и прочитайте путь, идущий вперед. Это ваш матч для регулярного выражения.
Нет особой гарантии того, когда или если вы достигнете начального состояния. Нужно выяснить, в каком смысле сгенерированные строки являются «случайными», и в каком смысле вы надеетесь на случайный элемент из языка в первую очередь.
Может быть, это отправная точка для размышления о проблеме, хотя!
Теперь, когда я это написал, мне кажется, что было бы проще неоднократно разрешать варианты, чтобы упростить шаблон регулярных выражений, пока у вас не останется простая строка. Найдите первый не алфавитный символ в шаблоне. Если это *, скопируйте предыдущий элемент несколько раз и удалите *. Если это |, выберите, какой из элементов OR будет сохранен, а остальные удалите. Для левой пары сделайте то же самое, но посмотрите на персонажа, следующего за соответствующей правой пареной. Это, вероятно, будет проще, если вы сначала проанализируете регулярное выражение в древовидном представлении, с которым будет легче работать со структурой группировки пар.
Для человека, который беспокоился, что решение о том, действительно ли регулярное выражение соответствует чему-либо, равносильно проблеме остановки: нет, обычные языки ведут себя довольно хорошо. Вы можете сказать, описывают ли любые два регулярных выражения один и тот же набор принятых строк. Вы в основном делаете машину выше, затем следуете алгоритму, чтобы произвести канонический минимальный эквивалент машины. Сделайте это для двух регулярных выражений, затем проверьте, эквивалентны ли получающиеся минимальные машины, что просто.