Как написать регулярное выражение для этих выражений пути - PullRequest
1 голос
/ 01 июля 2010

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

  1. item.sub_element.subsubelement(@key = string);или
  2. item..subsub_element(@key = string);или
  3. //subsub_element(@key = string);или,
  4. item(@key = string)

как бы выглядело регулярное выражение, соответствующее этим?

Я пришел к следующему:

 ((/{2}?[\\w+_*])(\\([_=@#\\w+\\*\\(\\)\\{\\}\\[\\]]*\\))?\\.{0,2})+

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

Однако в четвертом примере выполняется тестовый запуск сMatcher.matches () возвращает false.Итак, где моя ошибка?

Есть идеи?

TIA,

FK

Редактировать: от попытки с http://www.regexplanet.com/simple/index.html кажется, яне знал о разнице между Matcher.matches() и Matcher.find() методами объекта Matcher.Я пытался разбить входную строку на подстроки, которые соответствуют моему регулярному выражению.Следовательно, мне нужно использовать find(), а не matches().

Edit2: Это делает трюк

([a-zA-Z0-9 _] +) \. {0,2} (\ (. * \))?

Ответы [ 3 ]

3 голосов
/ 01 июля 2010

Я думаю, вы неправильно понимаете классы персонажей.Я обнаружил, что для тестирования регулярных выражений http://gskinner.com/RegExr/ очень помогает.В качестве учебного пособия по регулярным выражениям я бы порекомендовал http://www.regular -expressions.info / tutorial.html .

Я не совсем уверен, как вы хотите сгруппировать свои строки.Ваше предложение, похоже, предполагает, что ваша первая группа - это просто item часть item..subsub_element(@key = string), но тогда я не уверен, какой должна быть вторая группа.Судя по тому, что я вывел из вашего регулярного выражения, я просто сгруппирую часть перед скобками в первую группу, а часть в скобках во вторую группу.Вы можете изменить это, если я вас неправильно понял.

Я не экранирую выражение для Java, поэтому вам придется это сделать.=)

Первая группа должна начинаться с дополнительной двойной косой черты.Я использую (?://)?.Здесь ?: означает, что эта часть не должна быть захвачена, а последняя ? делает группу перед ней необязательной.

После этого появляются слова, содержащие символы и подчеркивания, сгруппированные по точкам.Одно такое слово (с конечными точками) может быть представлено как [a-zA-Z_]+\.{0,2}.Я думаю, что \w, который вы используете, является сокращением для [a-zA-Z0-9_].Он НЕ представляет слово, но является «символом слова».

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

((?://)?(?:[a-zA-Z_]+\.{0,2})+)

Длячасть в скобках, можно использовать \([^)]*\), что означает открывающую скобку (экранированная, поскольку она имеет специальное значение, за которой следует произвольное количество не квадратных скобок (не экранированная, так как она не имеет специального значения внутри класса символов)и затем закрывающая скобка.

В сочетании с ^ и $ для обозначения начала и конца строки соответственно мы получим

^((?://)?(?:[a-zA-Z_]+\.{0,2})+)(\([^)]*\))$

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

3 голосов
/ 01 июля 2010

Вы можете найти этот сайт полезным для тестирования вашего регулярного выражения http://www.fileformat.info/tool/regex.htm.

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

0 голосов
/ 01 июля 2010

В вашем шаблоне так много неправильного:

/{2}?: что, по вашему мнению, ? означает здесь?Потому что, если вы думаете, что /{2} необязательно, вы ошибаетесь.Вместо этого ? является модификатором нежелания для повторения {2}.Возможно, что-то вроде (?:/{2})? - это то, что вы намереваетесь.

[\w+_*]: что, по вашему мнению, + и * означает здесь?Потому что, если вы думаете, что они представляют повторение, вы ошибаетесь.Это определение класса символов, и + и * буквально означают символы + и *.Возможно, вы намерены ... на самом деле я не уверен, что вы намерены.


Попытка решения

Вот попытка угадать, что ваша спецификация:

    String PART_REGEX =
        "(word)(?:<<@(word) = (word)>>)?"
            .replace("word", "\\w+")
            .replace(" ", "\\s*")
            .replace("<<", "\\(")
            .replace(">>", "\\)");
    Pattern entirePattern = Pattern.compile(
        "(?://)?part(?:\\.{1,2}part)*"
            .replace("part", PART_REGEX)
    );
    Pattern partPattern = Pattern.compile(PART_REGEX);

Затем мы можем проверить это следующим образом:

    String[] tests = {
        "item.sub_element.subsubelement(@key = string)",
        "item..subsub_element(@key = string)",
        "//subsub_element(@key = string)",
        "item(@key = string)",
        "one.dot",
        "two..dots",
        "three...dots",
        "part1(@k1=v1)..part2(@k2=v2)",
        "whatisthis(@k=v1=v2)",
        "noslash",
        "/oneslash",
        "//twoslashes",
        "///threeslashes",
        "//multiple//double//slashes",
        "//multiple..double..dots",
        "..startingwithdots",
    };
    for (String test : tests) {
        System.out.println("[ " + test + " ]");
        if (entirePattern.matcher(test).matches()) {
            Matcher part = partPattern.matcher(test);
            while (part.find()) {
                System.out.printf("  [%s](%s => %s)%n",
                    part.group(1),
                    part.group(2),
                    part.group(3)
                );
            }
        }
    }

Вышеуказанные отпечатки:

[ item.sub_element.subsubelement(@key = string) ]
  [item](null => null)
  [sub_element](null => null)
  [subsubelement](key => string)
[ item..subsub_element(@key = string) ]
  [item](null => null)
  [subsub_element](key => string)
[ //subsub_element(@key = string) ]
  [subsub_element](key => string)
[ item(@key = string) ]
  [item](key => string)
[ one.dot ]
  [one](null => null)
  [dot](null => null)
[ two..dots ]
  [two](null => null)
  [dots](null => null)
[ three...dots ]
[ part1(@k1=v1)..part2(@k2=v2) ]
  [part1](k1 => v1)
  [part2](k2 => v2)
[ whatisthis(@k=v1=v2) ]
[ noslash ]
  [noslash](null => null)
[ /oneslash ]
[ //twoslashes ]
  [twoslashes](null => null)
[ ///threeslashes ]
[ //multiple//double//slashes ]
[ //multiple..double..dots ]
  [multiple](null => null)
  [double](null => null)
  [dots](null => null)
[ ..startingwithdots ]

Вложения

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