Java正则匹配时appendReplacement()和appendTail()用法
最近接触mdx语句较多,需要做些mdx相关的语句处理,用了一下appendReplacement和appendTail方法,为了备忘,此处mark一下。
appendReplacement:将当前匹配的子字符串替换为指定的字符串,并且将替换后的字符串及其之前到上次匹配的子字符串之后的字符串添加到一个StringBuffer对象中。
appendTail:将最后一次匹配之后剩余的字符串添加到一个StringBuffer对象中。
原语句类似结构如下:
WITH MEMBER [SELLER_COUNTRY].[COUNTRY].[Microsoft.Mashup.Engine.FilterContext] AS ' AGGREGATE(
{
China
}
)'
SELECT
NON EMPTY{
[Measures].[GMV_SUM]
}ON 0,
NON EMPTY CROSSJOIN(
{
[SELLER_COUNTRY].[COUNTRY].[Microsoft.Mashup.Engine.FilterContext]
},
{
[BUYER_COUNTRY].[COUNTRY].[CN]
}
)
PROPERTIES MEMBER_CAPTION, MEMBER_UNIQUE_NAME ON 1
FROM [test] CELL PROPERTIES VALUE
需要将 { China } 里的china更改为全限定名,即改为[SELLER_COUNTRY].[COUNTRY].[China]。于是此处进行匹配替换。源码大概如下,欢迎指正:
private static final Pattern ValuePattern = Pattern.compile("WITH MEMBER [\\s\\S]+?\\)'");
private static final Pattern valueFormatPattern = Pattern.compile("\\[[\\s\\S]+?\\[Microsoft.Mashup.Engine.FilterContext\\]");
private static final Pattern originValuePattern = Pattern.compile("\\{[\\s\\S]+?\\}");
public String changeValueFormat(String mdx){
StringBuffer result = new StringBuffer();
Matcher m = ValuePattern.matcher(mdx);
String format = "";
while (m.find()){
StringBuffer sb = new StringBuffer();
Matcher n = valueFormatPattern.matcher(m.group());
while(n.find()){
format = n.group().replaceAll("\\[Microsoft.Mashup.Engine.FilterContext\\]","");
}
Matcher l = originValuePattern.matcher(m.group());
while(l.find()){
String tmp = l.group().replaceAll("\\{","");
tmp=tmp.replaceAll("\\}","");
format ="{" + format + "\\[" + tmp.trim() + "\\]" + "}";
if(! "".equals(format)){
l.appendReplacement(sb, format);
}
}
l.appendTail(sb);
if(! "".equals(sb.toString())){
m.appendReplacement(result, sb.toString());
}
}
m.appendTail(result);
return result.toString();
}
优化
以上方法还是太Low,冗长。用了多个pattern,简单逻辑复杂化,代码不易读。其实只要合理利用Matcher的分组概念,分组捕获,然后替换掉你想修改的部分,最后再拼接起来即可,代码会简洁很多。如下:
private static final Pattern dimensionValuePattern = Pattern.compile("(?i)(MEMBER)([\\s\\S]*)(AS[\\s\\S]+?AGGREGATE\\()([\\s\\S]+?)(\\)\\')");
public String changeValueFormat(String mdx) {
StringBuffer result = new StringBuffer();
Matcher valueMatcher = dimensionValuePattern.matcher(mdx);
while (valueMatcher.find()) {
String preName = valueMatcher.group(2);
preName = preName.replaceAll("\\[Microsoft.Mashup.Engine.FilterContext\\]", "").trim();
String[] preNameArray = preName.split("\\.");
preName = preNameArray[0] + "." + preNameArray[1];
String lastName = valueMatcher.group(4);
lastName = lastName.replaceAll("\\{", "");
lastName = lastName.replaceAll("\\}", "").trim();
String tmp = valueMatcher.group(4).replaceAll(lastName, preName + ".[" + lastName + "]");
tmp = valueMatcher.group(1) + valueMatcher.group(2) + valueMatcher.group(3) + tmp + valueMatcher.group(5);
if (!"".equals(tmp)) {
valueMatcher.appendReplacement(result, tmp);
}
}
valueMatcher.appendTail(result);
return result.toString();
}