Java正则表达式 - 这段代码出了什么问题

时间:2012-03-04 19:04:28

标签: java regex

我正在尝试使用$()构造提取字符串中引用的属性的名称。例如,如果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 个答案:

答案 0 :(得分:2)

要回答您的具体问题,您应该关注group[1],而不是group[0]

Matcher.groupCount()方法在计数中不包含group[0],因此您的for循环永远不会显示group[1]匹配,因为i < matcher.groupCount()为false。

将您的条件更改为i <= matcher.groupCount(),您的输出会更具启发性。

那就是说,有更好的方法来做这个比写自己的正则表达式 - 例如http://api.dpml.net/ant/1.6.4/org/apache/tools/ant/filters/ExpandProperties.html

答案 1 :(得分:0)

无论指定的捕获组是什么,组0始终是整个匹配。最重要的是,Matcher.groupCount()返回捕获组的数量,不包括整个匹配。要获得您所追求的结果,请将for循环更改为以下内容(请注意,它从1开始,并且由于添加了等号而继续向前一步):

for (int i = 1; i <= matcher.groupCount(); i++) {