正则表达式匹配完全限定的类名
在文本中匹配完全限定的Java类名的最佳方式是什么?
示例: java.lang.Reflect
, java.util.ArrayList
, org.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
它们也可以不是保留字(如import
, true
或null
)。 如果你只想检查合理性,以上就足够了。 如果您还想检查有效性,则还必须检查保留字的列表。
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?