与完全限定类名匹配的正则表达式

在文本中匹配完全限定的 Java 类名的最佳方法是什么?

例子:。java.lang.Reflectjava.util.ArrayListorg.hibernate.Hibernate


答案 1

Java完全限定的类名(假设“N”)具有以下结构:

N.N.N.N

“N”部分必须是 Java 标识符。Java标识符不能以数字开头,但在初始字符之后,它们可以使用字母和数字,下划线或美元符号的任意组合:

([a-zA-Z_$][a-zA-Z\d_$]*\.)*[a-zA-Z_$][a-zA-Z\d_$]*
------------------------    -----------------------
          N                           N

它们也不能是保留字(如 、 或 )。如果您只想检查合理性,则上述内容就足够了。如果还想检查有效性,还必须检查保留字列表。importtruenull

Java标识符可以包含任何Unicode字母,而不是“仅拉丁语”。如果您也想检查这一点,请使用 Unicode 字符类:

([\p{Letter}_$][\p{Letter}\p{Number}_$]*\.)*[\p{Letter}_$][\p{Letter}\p{Number}_$]*

或者简称

([\p{L}_$][\p{L}\p{N}_$]*\.)*[\p{L}_$][\p{L}\p{N}_$]*

Java 语言规范(第 3.8 节)包含有关有效标识符名称的所有详细信息。

另请参阅此问题的答案:Java Unicode 变量名称


答案 2

这是一个完全工人阶级的测试,基于@alan-moore的出色评论

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.util.regex.Pattern;

import org.junit.Test;

public class ValidateJavaIdentifier {

    private static final String ID_PATTERN = "\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*";
    private static final Pattern FQCN = Pattern.compile(ID_PATTERN + "(\\." + ID_PATTERN + ")*");

    public static boolean validateJavaIdentifier(String identifier) {
        return FQCN.matcher(identifier).matches();
    }


    @Test
    public void testJavaIdentifier() throws Exception {
        assertTrue(validateJavaIdentifier("C"));
        assertTrue(validateJavaIdentifier("Cc"));
        assertTrue(validateJavaIdentifier("b.C"));
        assertTrue(validateJavaIdentifier("b.Cc"));
        assertTrue(validateJavaIdentifier("aAa.b.Cc"));
        assertTrue(validateJavaIdentifier("a.b.Cc"));

        // after the initial character identifiers may use any combination of
        // letters and digits, underscores or dollar signs
        assertTrue(validateJavaIdentifier("a.b.C_c"));
        assertTrue(validateJavaIdentifier("a.b.C$c"));
        assertTrue(validateJavaIdentifier("a.b.C9"));

        assertFalse("cannot start with a dot", validateJavaIdentifier(".C"));
        assertFalse("cannot have two dots following each other",
                validateJavaIdentifier("b..C"));
        assertFalse("cannot start with a number ",
                validateJavaIdentifier("b.9C"));
    }
}