将字符串转换为有效的Java变量名

7

我正在开发一款代码生成工具,需要将一个字符串转化为Java可用的变量名,但是我不确定最好的方法是什么。

例如:

"123 this is some message !" => _123_this_is_some_message(或类似名称)

谢谢!


2
输入字符串可能包含哪些内容?仅包含字母数字、标点符号和空格吗?还是包含Unicode中的所有内容? - Pops
不对输入施加规则,你会发现冲突(即多对一映射)。根据您的应用程序,这可能重要或不重要。 - jpm
如果它是Java变量名称的有效字符,您可以尝试循环遍历字符串并将其附加到StringBuilder中。您可能会遇到的挑战是重复变量,因此您可能需要跟踪已使用的内容,并在必要时附加数字。 - JustinKSU
因为输入字符串可以是任何内容,我考虑使用一些正则表达式来排除无效字符,并使用一些计数器来记住重复的内容,类似于这个链接中的示例:https://dev59.com/3HA75IYBdhLWcg3wboYz,但也许有更好的想法。 - Hugo Zapata
@HugoZapata,isJavaIdentifierPart() 和相关函数应该会有所帮助。 - millimoose
3个回答

11

假设您将所有无效字符替换为_,则以下代码可以工作(粗略示例)。您可能需要添加一些逻辑来处理名称冲突等。它基于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);
}

最好附加 '_'(而不是字符串 "_")的字符。 - NateS

4
您想要将随机字符串转换为有效的Java标识符。 根据Java语言规范,§3.8的定义,标识符的定义如下:

标识符:
标识符字符但不是关键字布尔字面值空字面值

标识符字符:
Java字母
标识符字符 Java字母或数字

Java字母:
任何Unicode字符都是Java字母

Java字母或数字:
任何Unicode字符都是Java字母或数字

然后,您需要逐个检查输入并将任何无效字符替换为有效字符(例如下划线)或完全删除它。 Java甚至提供了Character类中的方法,告诉您给定字符是否是Java字母Java字母或数字: isJavaIdentifierStart()isJavaIdentifierPart。(这比尝试排除无效字符要容易得多,因为有效字符集很小,而无效字符集很大。)
最后,请确保您的结果不以数字开头,也不是关键字或字面值。 如果可能并且不需要冲突,则可以根据需要附加数字以获得唯一值。

1

您应该:

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

因此,类似于以下内容:

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

这相当严格:使用您的第二点将排除许多有效字符。 - assylias
жіЁж„ҸпјҢJavaзҡ„\Wеә”иҜҘжҳҜUnicodeж„ҹзҹҘзҡ„пјҢеӣ жӯӨйқһеёёйҖӮеҗҲдҪңдёәйқһж ҮиҜҶз¬Ұеӯ—з¬Ұзҡ„е®ҡд№үгҖӮ - Joey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接