Как создать текст, соответствующий регулярному выражению, из регулярного выражения?
Да, вы это правильно поняли. Мне нужно что-то, что способно генерировать случайный текст из регулярного выражения. Таким образом, текст должен быть случайным, но соответствовать регулярному выражению. Кажется, этого не существует, но я могу ошибаться.
Просто пример: эта библиотека будет способна принимать "[ab]*c
" в качестве входных данных и создавать образцы, такие как:
abc
abbbc
BAC
и др.
Обновление: я сам что-то создал: Xeger. Проверьте http://code.google.com/p/xeger/.
Ответы
Ответ 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()));
}
Ответ 5
Вот реализация такого модуля на Python: http://www.mail-archive.com/[email protected]/msg125198.html Он должен быть переносимым на Java.