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

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

示例: java.lang.Reflectjava.util.ArrayListorg.hibernate.Hibernate


Java完全限定的类名称(可以说是“N”)具有结构

N.N.N.N

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

([a-zA-Z_$][a-zA-Zd_$]*.)*[a-zA-Z_$][a-zA-Zd_$]*
------------------------    -----------------------
          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变量名称


基于来自@ 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"));
    }
}

Renaud提供的模式起作用。 但是,据我所知,它会始终回溯到最后。

为了优化它,你可以将上半部分与上一半交换。 请注意您还需要更改点匹配。

以下是我的版本,与原始版本相比,运行速度快两倍:

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

我不能写评论,所以我决定写一个答案。

链接地址: http://www.djcxy.com/p/92743.html

上一篇: Regular expression matching fully qualified class names

下一篇: Regular expression to match DNS hostname or IP Address?