Регулярные выражения Java - что не так с этим кодом - PullRequest
1 голос
/ 04 марта 2012

Я пытаюсь извлечь имя свойства, на которое есть ссылка в строке, используя конструкцию $(). Например, если bb=xo-xo, то "aa$(bb)aa" расширяется до "aaxo-xoaa".

Вот код:

public static void main(String[] args) {
  final String PROPERTY_NAME_REGEX = "\\w+(?:\\.\\w+)*";
  final String PROPERTY_REFERENCE_REGEX = "\\$\\((" + PROPERTY_NAME_REGEX + ")\\)";
  Pattern pattern = Pattern.compile(PROPERTY_REFERENCE_REGEX);
  String value = "hhh $(aa.bbcc.dd) @jj $(aakfd) j";
  Matcher matcher = pattern.matcher(value);
  StringBuffer sb = new StringBuffer();
  while (matcher.find()) {
    System.out.println(String.format("\"%s\" at [%d-%d)",
      matcher.group(),
      matcher.start(),
      matcher.end()));
    for (int i = 0; i < matcher.groupCount(); ++i) {
      System.out.println(String.format("group[%d] = %s", i, matcher.group(i)));
    }
  }
}

И это отображает:

"$(aa.bbcc.dd)" at [4-17)
group[0] = $(aa.bbcc.dd)
"$(aakfd)" at [22-30)
group[0] = $(aakfd)

Но я надеялся получить следующий вывод:

"$(aa.bbcc.dd)" at [4-17)
group[0] = aa.bbcc.dd
"$(aakfd)" at [22-30)
group[0] = aakfd

Что я делаю не так?

Ответы [ 2 ]

2 голосов
/ 04 марта 2012

Чтобы ответить на вашу конкретную проблему, вы должны смотреть на group[1], а не group[0].

Метод Matcher.groupCount() не включает в себя group[0], поэтому ваш цикл for никогда не выполняетсяпоказывает group[1] совпадения, потому что i < matcher.groupCount() ложно.

Измените ваше состояние на i <= matcher.groupCount(), и ваш вывод будет более поучительным.

Тем не менее, есть лучшие способы сделать это, чем написать собственное регулярное выражение - например http://api.dpml.net/ant/1.6.4/org/apache/tools/ant/filters/ExpandProperties.html

0 голосов
/ 04 марта 2012

Группа 0 - это всегда полное совпадение, независимо от указанных групп захвата.Чтобы завершить это, Matcher.groupCount () возвращает количество групп захвата, исключая все совпадения.Чтобы получить результат, которого вы добились, измените цикл for на следующий (обратите внимание, что он начинается с 1 и продолжается еще на один шаг из-за добавленного знака равенства):

for (int i = 1; i <= matcher.groupCount(); i++) {
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...