驼峰式下划线,某些前缀除外
Underscore to camel case except for certain prefixes
我目前正在创建一个 Java 程序来重写我们软件中一些过时的 Java 类。部分转换包括将变量名称从包含下划线更改为使用驼峰命名法。问题是,我不能简单地替换代码中的所有下划线。我们有一些 类 带有常量,对于那些,下划线应该保留。
如何将 string_label 之类的实例替换为 stringLabel,但不要替换出现在前缀 "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();
}
也许你可以有另一个模式:
Pattern p = Pattern.compile("^Parameters.*"); //^ means the beginning of a line
如果匹配,请不要替换任何内容。
您可以尝试类似的方法:
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 语法,但我希望你明白我的意思。自己做一点解析会有很长的路要走。
我目前正在创建一个 Java 程序来重写我们软件中一些过时的 Java 类。部分转换包括将变量名称从包含下划线更改为使用驼峰命名法。问题是,我不能简单地替换代码中的所有下划线。我们有一些 类 带有常量,对于那些,下划线应该保留。
如何将 string_label 之类的实例替换为 stringLabel,但不要替换出现在前缀 "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();
}
也许你可以有另一个模式:
Pattern p = Pattern.compile("^Parameters.*"); //^ means the beginning of a line
如果匹配,请不要替换任何内容。
您可以尝试类似的方法:
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 语法,但我希望你明白我的意思。自己做一点解析会有很长的路要走。