Использование Regex для создания Strings, а не соответствовать их

голоса
87

Я пишу утилиту Java , который помогает мне генерировать нагрузки данных для тестирования производительности. Было бы очень здорово , чтобы иметь возможность задать регулярное выражение для строк так , что мой генератор выплевывает вещи , которые соответствуют этим. Есть ли что - то там уже запеченный которые я могу использовать , чтобы сделать это? Или есть библиотека , которая получает меня большую часть пути туда?

благодаря

Задан 22/08/2008 в 12:35
источник пользователем
На других языках...                            


12 ответов

голоса
30

Редактировать:

Как уже упоминалось в комментариях, есть библиотека доступна на Google Code , чтобы добиться этого: http://code.google.com/p/xeger

Смотрите также https://github.com/mifmif/Generex как предложено Mifmif

Исходное сообщение:

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

Если вы посмотрите на исходный код класса java.util.regex.Pattern, вы увидите, что он использует внутреннее представление экземпляров Node. Каждый из различных компонентов модели имеет свою собственную реализацию Узел подкласса. Эти узлы организованы в виде дерева.

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

Ответил 22/08/2008 в 12:54
источник пользователем

голоса
18

Xeger (Java) способен это делать , а также:

String regex = "[ab]{4,6}c";
Xeger generator = new Xeger(regex);
String result = generator.generate();
assert result.matches(regex);
Ответил 19/10/2009 в 20:32
источник пользователем

голоса
11

Это слишком поздно , чтобы помочь оригинальный плакат, но это может помочь новичку. Generex полезной библиотека Java , которая предоставляет множество возможностей для использования регулярных выражений для создания строк (генерации случайных чисел, генерируя строку , основанную на индексе, порождая все строки ...).

Пример :

Generex generex = new Generex("[0-3]([a-c]|[e-g]{1,2})");

// generate the second String in lexicographical order that matches the given Regex.
String secondString = generex.getMatchedString(2);
System.out.println(secondString);// it print '0b'

// Generate all String that matches the given Regex.
List<String> matchedStrs = generex.getAllMatchedStrings();

// Using Generex iterator
Iterator iterator = generex.iterator();
while (iterator.hasNext()) {
    System.out.print(iterator.next() + " ");
}
// it prints 0a 0b 0c 0e 0ee 0e 0e 0f 0fe 0f 0f 0g 0ge 0g 0g 1a 1b 1c 1e
// 1ee 1e 1e 1f 1fe 1f 1f 1g 1ge 1g 1g 2a 2b 2c 2e 2ee 2e 2e 2f 2fe 2f 2f 2g
// 2ge 2g 2g 3a 3b 3c 3e 3ee 3e 3e 3f 3fe 3f 3f 3g 3ge 3g 3g 1ee

// Generate random String
String randomStr = generex.random();
System.out.println(randomStr);// a random value from the previous String list
Ответил 09/07/2014 в 17:58
источник пользователем

голоса
4

Я пошел корень качения моей собственной библиотеки для этого (C # , но должен быть легко понять , для разработчиков Java).

Rxrdg начал в качестве решения проблемы создания тестовых данных для реального проекта жизни. Основная идея заключается в том, чтобы использовать существующие (регулярное выражение) шаблоны проверки для создания случайных данных, который соответствует таким моделям. Таким образом, действует случайным образом данных создается.

Это не то, что трудно написать парсер для простых шаблонов регулярных выражений. Использование абстрактного синтаксического дерева для создания строк должно быть еще проще.

Ответил 05/01/2009 в 13:39
источник пользователем

голоса
4

Visual Studio Team System делает включать что - то вроде этого. Проверьте это

Не много помощи для Java, хотя, так что извините.

Ответил 22/08/2008 в 12:58
источник пользователем

голоса
3

На StackOverflow подкаста 11:

Сполски: Да. Там новый продукт также, если вы не хотите использовать System Team там наши друзья в RedGate есть продукт под названием SQL Generator Data [ http://www.red-gate.com/products/sql_data_generator/index.htm] , Это $ 295, и он просто создает некоторые данные реалистичный тест. И это делает такие вещи , как на самом деле генерировать реальные города в колонке города , что на самом деле существуют, и тогда , когда он генерирует тот он будет получать государство права, вместо того , чтобы государство не так, или положить государства в немецкие города и тому подобные ... вы знаете, это создает довольно реалистичные данные. Я не совсем уверен , что все функции.

Это, вероятно, не то, что вы ищете, но это может быть хорошей трогании точки, вместо того, чтобы создавать свои собственные.

Я не могу найти что-нибудь в Google, так что я хотел бы предложить решения этой проблемы путем разбора данного регулярного выражения в мельчайшие единицы работы (\ ш, [хх], \ d и т.д.) и писать некоторые основные методы для поддержки эти регулярные выражения фразы.

Таким образом, для \ ж вы бы метод getRandomLetter (), который возвращает любые случайные письма, и вы бы также иметь getRandomLetter (обугленный startLetter, символ endLetter), что дает вам случайное письмо между этими двумя значениями.

Ответил 22/08/2008 в 13:07
источник пользователем

голоса
2

Я нахожусь на полете и видел только вопрос: я написал простым, но неэффективное и неполное решение. Я надеюсь, что это может помочь вам начать писать свой собственный парсер:

public static void main(String[] args) {

    String line = "[A-Z0-9]{16}";
    String[] tokens = line.split(line);
    char[] pattern = new char[100];
    int i = 0;
    int len = tokens.length;
    String sep1 = "[{";
    StringTokenizer st = new StringTokenizer(line, sep1);

    while (st.hasMoreTokens()) {
        String token = st.nextToken();
        System.out.println(token);

        if (token.contains("]")) {
            char[] endStr = null;

            if (!token.endsWith("]")) {
                String[] subTokens = token.split("]");
                token = subTokens[0];

                if (!subTokens[1].equalsIgnoreCase("*")) {
                    endStr = subTokens[1].toCharArray();
                }
            }

            if (token.startsWith("^")) {
                String subStr = token.substring(1, token.length() - 1);
                char[] subChar = subStr.toCharArray();
                Set set = new HashSet<Character>();

                for (int p = 0; p < subChar.length; p++) {
                    set.add(subChar[p]);
                }

                int asci = 1;

                while (true) {
                    char newChar = (char) (subChar[0] + (asci++));

                    if (!set.contains(newChar)) {
                        pattern[i++] = newChar;
                        break;
                    }
                }
                if (endStr != null) {
                    for (int r = 0; r < endStr.length; r++) {
                        pattern[i++] = endStr[r];
                    }
                }

            } else {
                pattern[i++] = token.charAt(0);
            }
        } else if (token.contains("}")) {
            char[] endStr = null;

            if (!token.endsWith("}")) {
                String[] subTokens = token.split("}");
                token = subTokens[0];

                if (!subTokens[1].equalsIgnoreCase("*")) {
                    endStr = subTokens[1].toCharArray();
                }
            }

            int length = Integer.parseInt((new StringTokenizer(token, (",}"))).nextToken());
            char element = pattern[i - 1];

            for (int j = 0; j < length - 1; j++) {
                pattern[i++] = element;
            }

            if (endStr != null) {
                for (int r = 0; r < endStr.length; r++) {
                    pattern[i++] = endStr[r];
                }
            }
        } else {
            char[] temp = token.toCharArray();

            for (int q = 0; q < temp.length; q++) {
                pattern[i++] = temp[q];
            }
        }
    }

    String result = "";

    for (int j = 0; j < i; j++) {
        result += pattern[j];
    }

    System.out.print(result);
}
Ответил 28/08/2012 в 02:38
источник пользователем

голоса
2

Я знаю , что есть уже принял ответ, но я использую генератор данных RedGate в (тот , упомянутый в ответе Крейга) , и она работает очень хорошо для всего , что я бросил на нее. Это быстро и что заставляет меня хотеть использовать то же регулярное выражение для создания реальных данных для таких вещей , как регистрация коды , что эта вещь выплевывает.

Требуется регулярное выражение, как:

[A-Z0-9]{3,3}-[A-Z0-9]{3,3}

и генерирует тонн уникальных кодов, таких как:

LLK-32U

Является ли это какой-то большой секрет алгоритм, который RedGate понял, и мы все не повезло или что-то, что нас простые смертные на самом деле могли бы сделать?

Ответил 29/10/2008 в 01:27
источник пользователем

голоса
1

Вы должны написать свой собственный парсер, подобно автору строки :: Random (Perl) сделал. На самом деле, он не использует регулярные выражения в любом месте в этом модуле, это именно то, что жемчужно-кодеры привыкли.

С другой стороны, может быть , вы можете посмотреть на источник , чтобы получить некоторые указатели.


EDIT: Черт, Блер бил меня на удар на 15 секунд.

Ответил 22/08/2008 в 12:53
источник пользователем

голоса
0

Это далеко от поддержки полного PCRE регулярного выражения, но я написал следующий метод Ruby, чтобы взять регулярное выражение типа строки и производить изменения на нем. (Для языка на основе CAPTCHA.)

# q = "(How (much|many)|What) is (the (value|result) of)? :num1 :op :num2?"
# values = { :num1=>42, :op=>"plus", :num2=>17 }
# 4.times{ puts q.variation( values ) }
# => What is 42 plus 17?
# => How many is the result of 42 plus 17?
# => What is the result of 42 plus 17?
# => How much is the value of 42 plus 17?
class String
  def variation( values={} )
    out = self.dup
    while out.gsub!( /\(([^())?]+)\)(\?)?/ ){
      ( $2 && ( rand > 0.5 ) ) ? '' : $1.split( '|' ).random
    }; end
    out.gsub!( /:(#{values.keys.join('|')})\b/ ){ values[$1.intern] }
    out.gsub!( /\s{2,}/, ' ' )
    out
  end
end

class Array
  def random
    self[ rand( self.length ) ]
  end
end
Ответил 11/11/2008 в 06:31
источник пользователем

голоса
-1

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

Ответил 17/07/2017 в 02:07
источник пользователем

голоса
-1

Если вы хотите создать «критическую» строку, вы можете рассмотреть следующие вопросы:

EGRET http://elarson.pythonanywhere.com/ , который генерирует «зло» строки , охватывающие регулярные выражения

MUTREX http://cs.unibg.it/mutrex/ , который генерирует обнаружения неисправностей строк с помощью регулярных выражений мутации

Оба академические инструменты (я один из авторов последнего) и работают достаточно хорошо.

Ответил 16/03/2017 в 03:10
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more