Могу ли я определить набор первых символов, соответствующих шаблону регулярного выражения?

StackOverflow https://stackoverflow.com/questions/787134

Вопрос

Я хотел бы иметь возможность вычислить набор всех символов, которые могут быть сопоставлены как первый символ в строке заданным экземпляром java.util.regex.Pattern.Более формально, учитывая, что DFA эквивалентен определенному регулярному выражению, мне нужен набор всех исходящих переходов из начального состояния.

Пример:

Pattern p = Pattern.compile("[abc]def|daniel|chris|\\s+");
Set<Character> first = getFirstSet(p);

Набор first должен содержать следующие элементы:

{ 'a', 'b', 'c', 'd', ' ', '\n', '\r', '\t' }

Есть идеи?Я прекрасно понимаю, что мог бы сам построить DFA и таким образом определить соответствующие состояния, но мне бы хотелось избежать подобных хлопот (читай:для меня это не так уж и дорого).Обратите внимание, что моим основным языком на самом деле является Scala, поэтому у меня есть доступ ко всем основным библиотекам Scala (какой бы они ни были).

Это было полезно?

Решение

Я думаю, вы могли бы проанализировать регулярное выражение и определить некоторую рекурсивную функцию, которая работает с проанализированным регулярным выражением слева направо, создавая такой набор первых.

Некоторые вещи просты:

  • Последовательность:first(r1r2) = first(r1) + (если '' в first(r1) first(r2) иначе пустой набор)
  • Чередование:первый(r1|r2) = первый(r1) + первый(r2)
  • Итерация:первый(r*) = первый(r) + ''
  • Персонажи:первый(с) = с
  • Классы персонажей:Сначала ([C1-CN]) = SET (C1, C2, ..., CN) ...

Распространите это на все примитивы и специальные флаги, которые знает ваш диалект регулярных выражений, и все готово.

Другие советы

Вы можете решить это рекурсивно...

  • Удалить закрывающую скобку и вызвать рекурсивно.
  • Разделите альтернативы верхнего уровня и рекурсивно вызывайте каждую часть.
  • Если альтернативы нет,
    • выведите все символы, начиная слева до первого необязательного символа.
    • Если есть группы символов, выведите все символы.

Вероятно, в этой идее много ошибок, но я бы попробовал именно это.Вам придется удалить утверждения, имена групп и тысячи других вещей.А если вы обнаружите класс инвертированных символов, например [^0-9], вам придется вывести много символов.

Поэтому я предполагаю, что это действительно сложная проблема.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top