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

Ответ сам.

Это проблема, связанная с связкой ключей, которая возникает, когда вы вызываете сервис через SSH.

26
задан unwind 22 April 2009 в 09:14
поделиться

10 ответов

There is text2re, a free web-based "regex by example" generator.

I don't think this is available in source code, though. I dare to say there is no automatic regex generator that gets it right without user intervention, since this would require the machine knowing what you want.


Note that text2re uses a template-based, modularized and very generalized approach to regular expression generation. The expressions it generates work, but they are much more complex than the equivalent hand-crafted expression. It is not a good tool to learn regular expressions because it does a pretty lousy job at setting examples.

For instance, the string "2009/11/12" would be recognized as a yyyymmdd pattern, which is helpful. The tool transforms it into this 125 character monster:

((?:(?:[1]{1}\d{1}\d{1}\d{1})|(?:[2]{1}\d{3}))[-:\/.](?:[0]?[1-9]|[1][012])[-:\/.](?:(?:[0-2]?\d{1})|(?:[3][01]{1})))(?![\d])

The hand-made equivalent would take up merely two fifths of that (50 characters):

([12]\d{3})[-:/.](0?\d|1[0-2])[-:/.]([0-2]?\d|3[01])\b
25
ответ дан 28 November 2019 в 07:10
поделиться

Невозможно написать общее решение для вашей проблемы. Проблема в том, что любой генератор, вероятно, не будет знать, что вы хотите проверить, например, следует ли разрешить "2312/45/67"? А как насчет «2009.11.12»?

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

12
ответ дан 28 November 2019 в 07:10
поделиться

Я попробовал очень наивный подход:

class RegexpGenerator {

    public static Pattern generateRegexp(String prototype) {
        return Pattern.compile(generateRegexpFrom(prototype));
    }

    private static String generateRegexpFrom(String prototype) {
        StringBuilder stringBuilder = new StringBuilder();

        for (int i = 0; i < prototype.length(); i++) {
            char c = prototype.charAt(i);

            if (Character.isDigit(c)) {
                stringBuilder.append("\\d");
            } else if (Character.isLetter(c)) {
                stringBuilder.append("\\w");
            } else { // falltrought: literal
                stringBuilder.append(c);
            }
        }

        return stringBuilder.toString();
    }

    private static void test(String prototype) {
        Pattern pattern = generateRegexp(prototype);
        System.out.println(String.format("%s -> %s", prototype, pattern));

        if (!pattern.matcher(prototype).matches()) {
            throw new AssertionError();
        }
    }

    public static void main(String[] args) {
        String[] prototypes = {
            "2009/11/12",
            "I'm a test",
            "me too!!!",
            "124.323.232.112",
            "ISBN 332212"
        };

        for (String prototype : prototypes) {
            test(prototype);
        }
    }
}

вывод:

2009/11/12 -> Я тест -> \ w '\ w \ w \ w \ w \ w \ w
я тоже!!! -> \ w \ w \ w \ w \ w !!!
124.323.232.112 -> \ d \ d \ d. \ D \ d \ d. \ D \ d \ d. \ D \ d \ d
ISBN 332212 -> \ w \ w \ w \ w \ d \ d \ d \ d \ d \ d

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

3
ответ дан 28 November 2019 в 07:10
поделиться

No, you cannot get a regex that matches what you want reliably, since the regex would not contain semantic information about the input (i.e. it would need to know it's generating a regex for dates). If the issue is with dates only I would recommend trying multiple regular expressions and see if one of them matches all.

1
ответ дан 28 November 2019 в 07:10
поделиться

I'm not sure if this is possible, at least not without many sample strings and some learning algorithm.

There are many regex' that would match and it's not possible for a simple algorithm to pick the 'right' one. You'd need to give it some delimiters or other things to look for, so you might as well just write the regex yourself.

1
ответ дан 28 November 2019 в 07:10
поделиться

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

1
ответ дан 28 November 2019 в 07:10
поделиться

I don't remember the name but if my theory of computation cells serve me right its impossible in theory :)

0
ответ дан 28 November 2019 в 07:10
поделиться

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

Спасибо всем, кто ответил (парень, за исключением (. *) - шутки замечательные. , но этот был sssssssssoooo хромой :))

0
ответ дан 28 November 2019 в 07:10
поделиться

Простите, но то, что вы все называете невозможным, явно достижимая задача. Он не сможет дать результаты для ВСЕХ примеров, и, возможно, не самые лучшие результаты, но вы можете дать ему различные подсказки, и это упростит жизнь. Далее следуют несколько примеров.

Также был бы очень полезен читаемый вывод, транслирующий результат. Примерно так:

  • "Искать: слово, начинающееся с нечисловой буквы и заканчивающееся строкой:" ing ".
  • или: Искать: текст, в котором есть bbb, за которым следует где-то zzz
  • или: * Искать: шаблон, который выглядит так: "aa / bbbb / cccc", где "/" - разделитель, "aa" - две цифры, "bbbb" - слово любой длины и "cccc" четыре цифры между 1900 и 2020 годами *

Возможно, мы могли бы создать «обратный переводчик» с языком типа SQL для создания регулярного выражения, вместо того, чтобы создавать его на компьютерном языке.

Вот несколько примеров, которые можно выполнить:

class Hint: 
  Properties: HintType, HintString
  enum HintType { Separator, ParamDescription, NumberOfParameters }
  enum SampleType { FreeText, DateOrTime, Formatted, ... }
  public string RegexBySamples( List<T> samples, 
         List<SampleType> sampleTypes, 
         List<Hint> hints, 
         out string GeneralRegExp, out string description, 
         out string generalDescription)...

regex = RegExpBySamples( {"11/November/1999", "2/January/2003"}, 
                     SampleType.DateOrTime, 
                     new HintList( HintType.NumberOfParameters, 3 ));

regex = RegExpBySamples( "123-aaaaJ-1444", 
                         SampleType.Format, HintType.Seperator, "-" );

Графический интерфейс, в котором вы помечаете образец текста или вводите его, также возможно добавление в регулярное выражение. Сначала вы отмечаете дату («образец») и выбираете, если этот текст уже отформатирован, или, если вы создаете формат, а также тип формата: свободный текст, форматированный текст, дата, GUID или Выбрать ... из существующих форматов (которые вы можете хранить в библиотеке).

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

4
ответ дан 28 November 2019 в 07:10
поделиться

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

1
ответ дан 28 November 2019 в 07:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: