Подтвердить что ты не робот

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

Да, вы это правильно поняли. Мне нужно что-то, что способно генерировать случайный текст из регулярного выражения. Таким образом, текст должен быть случайным, но соответствовать регулярному выражению. Кажется, этого не существует, но я могу ошибаться.

Просто пример: эта библиотека будет способна принимать "[ab]*c" в качестве входных данных и создавать образцы, такие как:

abc
abbbc
BAC

и др.

Обновление: я сам что-то создал: Xeger. Проверьте http://code.google.com/p/xeger/.

4b9b3361

Ответ 1

Я только что создал библиотеку для этого минуту назад. Он размещался здесь: http://code.google.com/p/xeger/. Перед использованием внимательно прочитайте инструкции. (Особенно тот, который ссылается на загрузку другой необходимой библиотеки.); -)

Так вы его используете:

String regex = "[ab]{4,6}c";
Xeger generator = new Xeger(regex);
String result = generator.generate();
assert result.matches(regex);

Ответ 2

Мне не известно о такой библиотеке. Если вы заинтересованы в написании одного из них, то это, вероятно, шаги, которые вам нужно предпринять:

  • Напишите парсер для регулярных выражений (вы можете начать с ограниченного класса регулярных выражений).

  • Используйте результат для построения NFA.

  • (Необязательно) Преобразуйте NFA в DFA.

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

В результате получается слово, которое принимается исходным регулярным выражением. Более подробно см., Например, Преобразование регулярного выражения в детерминированный конечный автомат.

Ответ 3

Вот несколько реализаций такого зверя, но ни один из них в Java (и все, кроме Microsoft с ограниченным исходным кодом, очень ограничены в поддержке функций регулярных выражений).

Ответ 4

на основе решения Уилфреда Спрингера вместе с http://www.brics.dk/~amoeller/automaton/ Я создаю еще один генератор. Он не использует рекурсию. В качестве входных данных необходимо ввести минимальное количество строк и максимальную длину строки. Результатом является принятая строка между минимальной и максимальной длиной. Это также позволяет некоторые из "коротких символов символов" XML. Я использую это для генератора образцов XML, который строит допустимую строку для фасетов.

public static final String generate(final String pattern, final int minLength, final int maxLength) {
    final String regex = pattern
            .replace("\\d", "[0-9]")        // Used d=Digit
            .replace("\\w", "[A-Za-z0-9_]") // Used d=Word
            .replace("\\s", "[ \t\r\n]");   // Used s="White"Space
    final Automaton automaton = new RegExp(regex).toAutomaton();
    final Random random = new Random(System.nanoTime());
    final List<String> validLength = new LinkedList<>();
    int len = 0;
    final StringBuilder builder = new StringBuilder();
    State state = automaton.getInitialState();
    Transition[] transitions;
    while(len <= maxLength && (transitions = state.getSortedTransitionArray(true)).length != 0) {
        final int option = random.nextInt(transitions.length);
        if (state.isAccept() && len >= minLength && len <= maxLength) validLength.add(builder.toString());
        final Transition t = transitions[option]; // random transition
        builder.append((char) (t.getMin()+random.nextInt(t.getMax()-t.getMin()+1))); len ++;
        state = t.getDest();
    }
    if(validLength.size() == 0) throw new IllegalArgumentException(automaton.toString()+" , "+minLength+" , "+maxLength);
    return validLength.get(random.nextInt(validLength.size()));
}