我正在尝试使用$()
构造提取字符串中引用的属性的名称。例如,如果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
我做错了什么?
要回答您的特定问题,您应该查看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
无论任何指定的捕获组如何,组0始终是整个匹配。最重要的是,Matcher.groupCount()返回捕获组的数量,不包括整个匹配。要获得您想要的结果,请将for循环更改为以下内容(请注意,它从1开始,并由于添加了等号而继续前进一步):
for (int i = 1; i <= matcher.groupCount(); i++) {