【问题标题】:Convert string to valid Java variable name将字符串转换为有效的 Java 变量名
【发布时间】:2012-09-27 02:12:09
【问题描述】:

对于我正在开发的代码生成工具,我需要获取一个字符串并从中生成一个有效的 java 变量名,但我不确定最好的方法。

例如:

"123 this is some message !" => _123_this_is_some_message(或类似的东西)

谢谢

【问题讨论】:

  • 输入字符串的可能内容是什么?只是字母数字、标点符号和空格? Unicode 中的所有内容?
  • 如果不对输入施加规则,我认为您会发现冲突(即多对一映射)。根据您的应用程序,这可能重要也可能不重要。
  • 如果它是 Java 变量名的有效字符,您可以尝试遍历字符串并附加到 StringBuilder。您可能面临的挑战是重复变量,因此您可能希望跟踪您使用的内容并在必要时附加数字。
  • 因为输入字符串可能是我正在考虑的任何内容.
  • @HugoZapata isJavaIdentifierPart() 和朋友应该帮忙

标签: java regex code-generation


【解决方案1】:

假设您用_ 替换所有无效字符,类似下面的代码可以工作(粗略示例)。您可能想为名称冲突等添加一些逻辑。它基于on the JLS #3.8

标识符是 Java 字母和 Java 数字的无限长度序列,其中第一个必须是 Java 字母。
[...]
“Java 字母”是 Character.isJavaIdentifierStart(int) 方法返回 true 的字符。
“Java 字母或数字”是 Character.isJavaIdentifierPart(int) 方法返回 true 的字符。

public static void main(String[] args) {
    String s = "123 sdkjh s;sdlkjh d";
    StringBuilder sb = new StringBuilder();
    if(!Character.isJavaIdentifierStart(s.charAt(0))) {
        sb.append("_");
    }
    for (char c : s.toCharArray()) {
        if(!Character.isJavaIdentifierPart(c)) {
            sb.append("_");
        } else {
            sb.append(c);
        }
    }

    System.out.println(sb);
}

【讨论】:

  • 还不如追加'_'(char而不是字符串"_")。
【解决方案2】:

您希望将随机字符串转换为有效的 Java 标识符。根据the Java Language Specification, §3.8,标识符的定义如下:

Identifier
IdentifierChars 但不是 KeywordBooleanLiteralNullLiteral em>

IdentifierChars
JavaLetter
IdentifierChars JavaLetterOrDigit

JavaLetter:
任何作为 Java 字母的 Unicode 字符

JavaLetterOrDigit:
任何作为 Java 字母或数字的 Unicode 字符

那么,您所要做的就是逐步检查您的输入并将任何无效字符替换为有效字符(例如下划线)或将其完全删除。 Java 甚至在Character 类中提供方法,告诉您给定字符是JavaLetter 还是JavaLetterOrDigitisJavaIdentifierStart()isJavaIdentifierPart。 (这比尝试排除无效字符要容易得多,因为有效字符集很小,而无效字符集很大。)

最后,请记住确保您的结果不是以数字 a 开头,而不是关键字或文字。如果冲突是可能的且不希望发生,您可以根据需要在结果中附加数字以获得唯一值。

【讨论】:

    【解决方案3】:

    你应该:

    1. \\s+ 替换为_
    2. 删除所有出现的\\W+
    3. 添加_ 作为前缀,如果^\d 匹配(或者即使不匹配)

    类似

    "_" + myString.replaceAll("\\s+", "_").replaceAll("\\W+", "")
    

    【讨论】:

    • 这是非常严格的:您的第 2 点将排除许多有效字符。
    • assylias,注意 Java 的 \W 应该是 Unicode 感知的,因此非常适合非标识符字符的定义。
    猜你喜欢
    • 2011-08-27
    • 2010-12-04
    • 2011-03-19
    • 2015-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多