我需要转换任意字符串:
到有效的Java标识符:
此任务是否有现有工具?
有了这么多Java源代码重构/生成框架,人们会认为这应该是非常常见的任务。
答案 0 :(得分:11)
这个简单的方法会将任何输入字符串转换为有效的java标识符:
public static String getIdentifier(String str) {
try {
return Arrays.toString(str.getBytes("UTF-8")).replaceAll("\\D+", "_");
} catch (UnsupportedEncodingException e) {
// UTF-8 is always supported, but this catch is required by compiler
return null;
}
}
示例:
"%^&*\n()" --> "_37_94_38_42_10_56_94_40_41_"
任何输入字符都可以使用 - 外语字符,换行符,任何东西!
另外,这个算法是:
str1.equals(str2)
感谢UTF-8
提出public static String getIdentifier(String str) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
if ((i == 0 && Character.isJavaIdentifierStart(str.charAt(i))) || (i > 0 && Character.isJavaIdentifierPart(str.charAt(i))))
sb.append(str.charAt(i));
else
sb.append((int)str.charAt(i));
}
return sb.toString();
}
建议
如果冲突正常(两个输入字符串可能产生相同的结果),此代码产生可读输出:
{{1}}
它保留有效标识符的字符,仅将那些无效的字符转换为它们的十进制等值。
答案 1 :(得分:3)
我不知道用于此目的的工具,但可以使用Character类轻松创建。
您知道字符串€with_special_characters ___是合法的java标识符吗?
public class Conv {
public static void main(String[] args) {
String[] idents = { "string with spaces", "100stringsstartswithnumber",
"string€with%special†characters/\\!", "" };
for (String ident : idents) {
System.out.println(convert(ident));
}
}
private static String convert(String ident) {
if (ident.length() == 0) {
return "_";
}
CharacterIterator ci = new StringCharacterIterator(ident);
StringBuilder sb = new StringBuilder();
for (char c = ci.first(); c != CharacterIterator.DONE; c = ci.next()) {
if (c == ' ')
c = '_';
if (sb.length() == 0) {
if (Character.isJavaIdentifierStart(c)) {
sb.append(c);
continue;
} else
sb.append('_');
}
if (Character.isJavaIdentifierPart(c)) {
sb.append(c);
} else {
sb.append('_');
}
};
return sb.toString();
}
}
打印
string_with_spaces
_100stringsstartswithnumber
string€with_special_characters___
_
答案 2 :(得分:1)
如果您为自动生成的代码执行此操作(即,不要太在意可读性),我最喜欢的一个就是Base64它。没有必要让语言律师知道哪些字符在编码中有效,这是“保护”任意字节数据的一种非常常见的方式。
答案 3 :(得分:1)
有了这么多Java源代码重构/生成框架,人们会认为这应该是非常常见的任务。
实际上并非如此。
代码重构框架将从现有的有效java标识符开始,通过将它们与一些其他字符连接起来,可以生成新的标识符,以用于消除歧义。
典型的代码生成框架将从受限字符集中的“名称”开始。它不必处理任意字符。
我认为转换器的目的是生成类似于输入字符串的标识符(如果可能的话)。如果是这种情况,我会按原样映射所有合法标识符字符进行转换,并用“$ xxxx”替换非法标识符字符,其中“xxxx”是Java 16位字符的4位十六进制编码。
您的方案也有效,但用'_'替换所有非法字符更有可能导致标识符冲突;即两个输入字符串映射到相同标识符的位置。
这是代码直截了当的,所以我会留给你做。