14

文字列入力がコーディング用の有効なJava変数であるかどうかを確認するにはどうすればよいですか? 私はこれを喜んで行う最初の人ではないと確信しています。しかし、何か役立つものを見つけるための適切なキーワードが欠けているのかもしれません。

おそらく、次のことをチェックする RegEx が最適でしょう。

  • 手紙で始まる

  • 数字、文字を含めることができます

  • 「_」のようないくつかの特殊文字を含めることができます (どの?)

  • 空白区切りを含めることはできません
4

2 に答える 2

20
public static boolean isValidJavaIdentifier(String s) {
    if (s.isEmpty()) {
        return false;
    }
    if (!Character.isJavaIdentifierStart(s.charAt(0))) {
        return false;
    }
    for (int i = 1; i < s.length(); i++) {
        if (!Character.isJavaIdentifierPart(s.charAt(i))) {
            return false;
        }
    }
    return true;
}

編集: @Joey が示すように、キーワードと予約語も除外する必要があります。

于 2013-03-15T16:52:12.637 に答える
14

Java 6+

使用する

import javax.lang.model.SourceVersion;

boolean isValidVariableName(CharSequence name) {
    return SourceVersion.isIdentifier(name) && !SourceVersion.isKeyword(name);
}

文字列が最新バージョンの Javaで有効な Java 変数名であるかどうかを確認する必要がある場合、または

import javax.lang.model.SourceVersion;

boolean isValidVariableNameInVersion(CharSequence name, SourceVersion version) {
    return SourceVersion.isIdentifier(name) && !SourceVersion.isKeyword(name, version);
}

文字列が特定のJava バージョンで有効な Java 変数名であるかどうかを確認する必要がある場合。

たとえば、アンダースコアは Java 9 から予約済みのキーワードになったためisValidVariableNameInVersion("_", SourceVersion.RELEASE_9)returnfalseisValidVariableNameInVersion("_", SourceVersion.RELEASE_8)に return true.

使い方

SourceVersion.isIdentifier(CharSequence name)name が構文的に有効な識別子 (単純な名前) または最新のソース バージョンのキーワードであるかどうかをチェックします。!SourceVersion.isKeyword(name)キーワードに対して false を返します。その結果、SourceVersion.isIdentifier(name) && !SourceVersion.isKeyword(name)有効な識別子に対してのみ true を返します。

SourceVersion.isName(CharSequence name, SourceVersion version)name が構文的に有効な修飾名であるかどうかをチェックする組み込みメソッドでも同じアプローチが使用されます。これは、 true「apple.color」のような文字列に対して返されることを意味します。

public static boolean isName(CharSequence name, SourceVersion version) {
    String id = name.toString();

    for(String s : id.split("\\.", -1)) {
        if (!isIdentifier(s) || isKeyword(s, version))
            return false;
    }
    return true;
}

テスト

import org.junit.jupiter.api.Test;

import javax.lang.model.SourceVersion;

import static org.assertj.core.api.Assertions.assertThat;

public class ValidVariableNameTest {
    boolean isValidVariableName(CharSequence name) {
        return isValidVariableNameInVersion(name, SourceVersion.RELEASE_8);
    }

    boolean isValidVariableNameInVersion(CharSequence name, SourceVersion version) {
        return SourceVersion.isIdentifier(name) && !SourceVersion.isKeyword(name, version);
    }

    @Test
    void variableNamesCanBeginWithLetters() {
        assertThat(isValidVariableName("test")).isTrue();
        assertThat(isValidVariableName("e2")).isTrue();
        assertThat(isValidVariableName("w")).isTrue();
        assertThat(isValidVariableName("привет")).isTrue();
    }

    @Test
    void variableNamesCanBeginWithDollarSign() {
        assertThat(isValidVariableName("$test")).isTrue();
        assertThat(isValidVariableName("$e2")).isTrue();
        assertThat(isValidVariableName("$w")).isTrue();
        assertThat(isValidVariableName("$привет")).isTrue();
        assertThat(isValidVariableName("$")).isTrue();
        assertThat(isValidVariableName("$55")).isTrue();
    }

    @Test
    void variableNamesCanBeginWithUnderscore() {
        assertThat(isValidVariableName("_test")).isTrue();
        assertThat(isValidVariableName("_e2")).isTrue();
        assertThat(isValidVariableName("_w")).isTrue();
        assertThat(isValidVariableName("_привет")).isTrue();
        assertThat(isValidVariableName("_55")).isTrue();
    }

    @Test
    void variableNamesCannotContainCharactersThatAreNotLettersOrDigits() {
        assertThat(isValidVariableName("apple.color")).isFalse();
        assertThat(isValidVariableName("my var")).isFalse();
        assertThat(isValidVariableName(" ")).isFalse();
        assertThat(isValidVariableName("apple%color")).isFalse();
        assertThat(isValidVariableName("apple,color")).isFalse();
        assertThat(isValidVariableName(",applecolor")).isFalse();
    }

    @Test
    void variableNamesCannotStartWithDigit() {
        assertThat(isValidVariableName("2e")).isFalse();
        assertThat(isValidVariableName("5")).isFalse();
        assertThat(isValidVariableName("123test")).isFalse();
    }


    @Test
    void differentSourceVersionsAreHandledCorrectly() {
        assertThat(isValidVariableNameInVersion("_", SourceVersion.RELEASE_9)).isFalse();
        assertThat(isValidVariableNameInVersion("_", SourceVersion.RELEASE_8)).isTrue();

        assertThat(isValidVariableNameInVersion("enum", SourceVersion.RELEASE_9)).isFalse();
        assertThat(isValidVariableNameInVersion("enum", SourceVersion.RELEASE_4)).isTrue();
    }

    @Test
    void keywordsCannotBeUsedAsVariableNames() {
        assertThat(isValidVariableName("strictfp")).isFalse();
        assertThat(isValidVariableName("assert")).isFalse();
        assertThat(isValidVariableName("enum")).isFalse();

        // Modifiers
        assertThat(isValidVariableName("public")).isFalse();
        assertThat(isValidVariableName("protected")).isFalse();
        assertThat(isValidVariableName("private")).isFalse();

        assertThat(isValidVariableName("abstract")).isFalse();
        assertThat(isValidVariableName("static")).isFalse();
        assertThat(isValidVariableName("final")).isFalse();

        assertThat(isValidVariableName("transient")).isFalse();
        assertThat(isValidVariableName("volatile")).isFalse();
        assertThat(isValidVariableName("synchronized")).isFalse();

        assertThat(isValidVariableName("native")).isFalse();

        // Declarations
        assertThat(isValidVariableName("class")).isFalse();
        assertThat(isValidVariableName("interface")).isFalse();
        assertThat(isValidVariableName("extends")).isFalse();
        assertThat(isValidVariableName("package")).isFalse();
        assertThat(isValidVariableName("throws")).isFalse();
        assertThat(isValidVariableName("implements")).isFalse();

        // Primitive types and void
        assertThat(isValidVariableName("boolean")).isFalse();
        assertThat(isValidVariableName("byte")).isFalse();
        assertThat(isValidVariableName("char")).isFalse();
        assertThat(isValidVariableName("short")).isFalse();
        assertThat(isValidVariableName("int")).isFalse();
        assertThat(isValidVariableName("long")).isFalse();
        assertThat(isValidVariableName("float")).isFalse();
        assertThat(isValidVariableName("double")).isFalse();
        assertThat(isValidVariableName("void")).isFalse();

        // Control flow
        assertThat(isValidVariableName("if")).isFalse();
        assertThat(isValidVariableName("else")).isFalse();

        assertThat(isValidVariableName("try")).isFalse();
        assertThat(isValidVariableName("catch")).isFalse();
        assertThat(isValidVariableName("finally")).isFalse();

        assertThat(isValidVariableName("do")).isFalse();
        assertThat(isValidVariableName("while")).isFalse();
        assertThat(isValidVariableName("for")).isFalse();
        assertThat(isValidVariableName("continue")).isFalse();

        assertThat(isValidVariableName("switch")).isFalse();
        assertThat(isValidVariableName("case")).isFalse();
        assertThat(isValidVariableName("default")).isFalse();
        assertThat(isValidVariableName("break")).isFalse();
        assertThat(isValidVariableName("throw")).isFalse();

        assertThat(isValidVariableName("return")).isFalse();

        // Other keywords
        assertThat(isValidVariableName("this")).isFalse();
        assertThat(isValidVariableName("new")).isFalse();
        assertThat(isValidVariableName("super")).isFalse();
        assertThat(isValidVariableName("import")).isFalse();
        assertThat(isValidVariableName("instanceof")).isFalse();

        // Reserved keywords
        assertThat(isValidVariableName("goto")).isFalse();
        assertThat(isValidVariableName("const")).isFalse();
    }

    @Test
    void literalsCannotBeUsedAsVariableNames() {
        assertThat(isValidVariableName("null")).isFalse();
        assertThat(isValidVariableName("true")).isFalse();
        assertThat(isValidVariableName("false")).isFalse();
    }
}
于 2015-12-10T14:24:14.070 に答える