除了某些前缀之外,对驼峰案例进行下划线

时间:2015-04-28 15:54:43

标签: java regex camelcasing

我目前正在创建一个Java程序来重写我们软件中的一些过时的Java类。部分转换包括将变量名称从包含下划线更改为使用camelCase。问题是,我不能简单地替换代码中的所有下划线。我们有一些常量类,对于那些,下划线应该保留 如何用stringLabel替换string_label之类的实例,但是不要替换前缀为“Parameters”后出现的下划线?

我目前正在使用以下内容,显然不会处理某些前缀:

public String stripUnderscores(String line) { 
  Pattern p = Pattern.compile("_(.)");
  Matcher m = p.matcher(line);         
  StringBuffer sb = new StringBuffer(); 
  while(m.find()) { 
    m.appendReplacement(sb, m.group(1).toUpperCase()); 
  } 
  m.appendTail(sb); 
  return sb.toString(); 
}

2 个答案:

答案 0 :(得分:2)

您可以尝试类似:

Pattern.compile("(?<!(class\\s+Parameters.+|Parameters\\.[\\w_]+))_(.)")

使用negative lookbehind

使用某种理解范围界定语法的重构工具可能会更好。

如果您检查的是Parameters.is_module_installed这样的合格名称,那么您将替换

class Parameters {
    static boolean is_module_installed;
}

错误。还有更多像这样的角落案例。 (import static Parameters.*;等等。)

单独使用正则表达式对我来说似乎很麻烦。你可以使例程变得更聪明的一种方法是使用正则表达式来捕获标识符的表达式,然后你可以单独检查它:

static List<String> exclude = Arrays.asList("Parameters");

static String getReplacement(String in) {
    for(String ex : exclude) {
        if(in.startsWith(ex + "."))
            return in;
    }

    StringBuffer b = new StringBuffer();
    Matcher m = Pattern.compile("_(.)").matcher(in);
    while(m.find()) {
        m.appendReplacement(b, m.group(1).toUpperCase());
    }

    m.appendTail(b);
    return b.toString();
}

static String stripUnderscores(String line) { 
    Pattern p = Pattern.compile("([_$\\w][_$\\w\\d]+\\.?)+");
    Matcher m = p.matcher(line);         
    StringBuffer sb = new StringBuffer(); 
    while(m.find()) { 
        m.appendReplacement(sb, getReplacement(m.group())); 
    } 
    m.appendTail(sb); 
    return sb.toString(); 
}

但是这仍然会因此失败,例如class Parameters { is_module_installed; }

通过进一步细分每个表达式可以使其更加健壮:

static String getReplacement(String in) {
    if(in.contains(".")) {
        StringBuilder result = new StringBuilder();

        String[] parts = in.split("\\.");

        for(int i = 0; i < parts.length; ++i) {
            if(i > 0) {
                result.append(".");
            }

            String part = parts[i];

            if(i == 0 || !exclude.contains(parts[i - 1])) {
                part = getReplacement(part);
            }

            result.append(part);
        }

        return result.toString();
    }

    StringBuffer b = new StringBuffer();
    Matcher m = Pattern.compile("_(.)").matcher(in);
    while(m.find()) {
        m.appendReplacement(b, m.group(1).toUpperCase());
    }

    m.appendTail(b);
    return b.toString();
}

这会处理像

这样的情况
Parameters.a_b.Parameters.a_b.c_d

和输出

Parameters.a_b.Parameters.a_b.cD

这是不可能的Java语法,但我希望你明白我的意思。自己做一点解析会有很长的路要走。

答案 1 :(得分:0)

也许你可以拥有另一种模式:

Pattern p = Pattern.compile("^Parameters.*"); //^ means the beginning of a line

如果匹配,请不要替换任何内容。