[英]How to check if string is a valid class identifier?
有什么好的方法来检查某个字符串是否表示有效的(完全限定的)Java类名称? 例如, org.comPAny.ClassName
甚至mYcRAZYcLASSnAME
是有效的类名,但类似org..package.MyClass
或org.ClassName.
不是。 我想检查类名的有效性而不加载该类。
Java中是否有一些方便的方法来检查? 还是可以提供可以涵盖所有情况的正则表达式?
编辑:请不要建议第三方库。
如果您确实需要防弹解决方案,请用"\\\\."
分隔字符串"\\\\."
并先使用
Character.isJavaIdentifierStart
和一个循环
Character.isJavaIdentifierPart
检查部件是否为有效的标识符名称。
编辑: #split(String)
将该字符串解释为正则表达式,因此请确保将字符串除以"\\\\."
而不只是"."
正如您所期望的那样,您会以最不惊讶的原则为出发点。 糟糕的API设计! 这就是您没有使用语言的正则表达式文字所得到的……
Java平台的不同版本支持不同的Unicode版本。
因此,不同的版本将支持不同的有效标识符。
以下说明了BMP之外的标识符和Java保留字。
import java.util.Arrays;
public enum PackageName {
SIMPLE, QUALIFIED, INVALID;
public static final PackageName check(String name) {
PackageName ret = PackageName.INVALID;
int[] codePoint;
int index = 0, dotex = -1;
boolean needStart = true;
escape: {
if(name == null || name.isEmpty()) break escape;
if(name.codePointAt(0) == '.') break escape;
codePoint = name.codePoints().toArray();
while (index <= codePoint.length) {
if(index == codePoint.length) {
if(codePoint[index - 1] == '.'){
ret = PackageName.INVALID; break escape;}
int start = dotex + 1;
int end = index;
start = name.offsetByCodePoints(0, start);
end = name.offsetByCodePoints(0, end);
String test = name.substring(start, end);
if(!(Arrays.binarySearch(reserved, test) < 0)){
ret = PackageName.INVALID; break escape;}
if(!(ret == PackageName.QUALIFIED)) ret = PackageName.SIMPLE;
break escape;
}
if(codePoint[index] == '.') {
if(codePoint[index - 1] == '.'){
ret = PackageName.INVALID; break escape;}
else {
needStart = true;
int start = dotex + 1;
int end = index;
start = name.offsetByCodePoints(0, start);
end = name.offsetByCodePoints(0, end);
String test = name.substring(start, end);
if(!(Arrays.binarySearch(reserved, test) < 0)) break escape;
dotex = index;
ret = PackageName.QUALIFIED;
}
} else if(Character.isJavaIdentifierStart(codePoint[index])) {
if(needStart) needStart = false;
} else if((!Character.isJavaIdentifierPart(codePoint[index]))){
ret = PackageName.INVALID; break escape;
}
index++;
}
}
return ret;
}
private static final String[] reserved;
static {
reserved = new String[] { "abstract", "assert", "boolean", "break", "byte",
"case", "catch", "char", "class", "const", "continue", "default", "do",
"double", "else", "enum", "extends", "false", "final", "finally",
"float", "for", "if", "goto", "implements", "import", "instanceof",
"int", "interface", "long", "native", "new", "null", "package",
"private", "protected", "public", "return", "short", "static",
"strictfp", "super", "switch", "synchronized", "this", "throw",
"throws", "transient", "true", "try", "void", "volatile", "while" };
}
}
正确的方法是使用javax.lang.model.SourceVersion.isName方法(Java标准库的一部分)。
public static boolean isValidJavaIdentifier(String s)
{
// an empty or null string cannot be a valid identifier
if (s == null || s.length() == 0)
{
return false;
}
char[] c = s.toCharArray();
if (!Character.isJavaIdentifierStart(c[0]))
{
return false;
}
for (int i = 1; i < c.length; i++)
{
if (!Character.isJavaIdentifierPart(c[i]))
{
return false;
}
}
return true;
}
参考: http : //www.java2s.com/Code/Java/Reflection/根据Java语言规范检查是否给定的Stringisavalididentifier.htm
有一个很好的解决方案来解决您的问题:
public static boolean isFullyQualifiedClassname( String classname ) {
if (classname == null) return false;
String[] parts = classname.split("[\\.]");
if (parts.length == 0) return false;
for (String part : parts) {
CharacterIterator iter = new StringCharacterIterator(part);
// Check first character (there should at least be one character for each part) ...
char c = iter.first();
if (c == CharacterIterator.DONE) return false;
if (!Character.isJavaIdentifierStart(c) && !Character.isIdentifierIgnorable(c)) return false;
c = iter.next();
// Check the remaining characters, if there are any ...
while (c != CharacterIterator.DONE) {
if (!Character.isJavaIdentifierPart(c) && !Character.isIdentifierIgnorable(c)) return false;
c = iter.next();
}
}
return true;
}
来源: http : //www.java2s.com/Code/Java/Reflection/确定所提供的字符串是否代表格式正确的合格Java类名.htm
你见过这个吗 ?
这里的方法isValidIdentifier
* 检查提供的名称是否是有效的Java包名称部分或类标识符。
防弹解决方案可使用正则表达式轻松实现:
String NAME = "\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*";
String DOT = "\\.";
String DOTTED_NAME = NAME + "(?:" + DOT + NAME + ")*";
Pattern DOTTED_NAME_PATTERN = Pattern.compile(DOTTED_NAME);
boolean isJavaName(String name) {
Matcher matcher = DOTTED_NAME_PATTERN.matcher(name);
return matcher.matches();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.