您好我正在研究一种验证权限的算法, 权限由一系列由句点连接的标记定义, 例如:
this.is.a.permission
a.b.c.d
another.permission
权限还可以包含下面列出的特殊令牌:
星号:
magicFunction("this.is.a.permission", "this.is.*") // <-- return true
magicFunction("this.is.a.permission", "*") // <-- return true
magicFunction("this.is.a.permission", "random.*") // <-- return false
星号仅验证他的令牌和所有下一个
问号:
magicFunction("this.is.a.permission", "this.is.?.permission") // <-- return true
magicFunction("this.is.a.permission", "?.is.a.permission") // <-- return true
magicFunction("this.is.a.permission", "this.?.wrong") // <-- return false
问号只验证他的令牌
包含清单:
magicFunction("this.is.a.permission", "this.is.[a,permission,c].permission") // <-- return true
magicFunction("this.is.a.permission", "[this].is.a.[a,permission,c]") // <-- return true
magicFunction("this.is.a.permission", "this.[is,c,d].wrong") // <-- return false
包含列表仅在其自身包含时才验证令牌,由[argument,argument1,argument2,...]
定义
独家列表:
magicFunction("this.is.a.permission", "this.is.<b,c,d>.permission") // <-- return true
magicFunction("this.is.a.permission", "<everything>.is.a.<invalid>") // <-- return true
magicFunction("this.is.a.permission", "this.is.a.<permission,wrong>") // <-- return false
独占列表仅在其未包含的情况下验证令牌,由&lt; argument,argument1,argument2,...&gt;
定义
这是一个测试用例:
public class PermissionTest {
public static void main(String[] args) {
System.out.println(rightPad("PERMISSION", 35) + rightPad("PERMISSION EXPRESSION", 35) + "RESULT");
// ALL TRUE
assert magicFunction( "A.B.C", "A.B.C.D");
assert magicFunction( "A.B.C.D", "A.B.C.D");
assert magicFunction( "A.B.C.D", "A.B.*");
assert magicFunction( "A.B.C.D", "A.B.?.D");
assert magicFunction( "A.B.C.D", "A.B.C.[D,E,F]");
assert magicFunction( "A.B.C.E", "A.B.C.[D,E,F]");
assert magicFunction( "A.B.C.F", "A.<A,C>.C.[D,E,F]");
assert magicFunction( "A.B.C.D", "A.B.C.<A,B,C>");
assert magicFunction( "A.B.C.E", "A.B.C.<A,B,C>");
assert magicFunction( "A.B.C.F", "A.[B].C.<A,B,C>");
System.out.println();
// ALL FALSE
assert !magicFunction( "A.B.C", "A.B");
assert !magicFunction( "A.B.C.D", "A.B.?.E");
assert !magicFunction( "A.B.C.D", "A.D.*");
assert !magicFunction( "A.B.C.D", "A.B.?");
assert !magicFunction( "A.B.C.Q", "A.?.C.[D,E,F]");
assert !magicFunction( "A.B.C.W", "A.?.C.[D,E,F]");
assert !magicFunction( "A.B.C.E", "A.<B,D,E>.?.[D,E,F]");
assert !magicFunction( "A.B.C.A", "A.B.C.<A,B,C>");
assert !magicFunction( "A.B.C.B", "A.B.C.<A,B,C>");
assert !magicFunction( "A.B.C.C", "A.[D].C.<A,B,C>");
}
public static boolean magicFunction(String permission, String permissionExpression) {
boolean value = magicFunctionImplementation(permission, permissionExpression);
System.out.println(
rightPad(permissionExpression, 35) +
rightPad(permission, 35) +
value
);
return value;
}
/**
* The function implementation
*
* IMPLEMENT YOUR FUNCTION HERE
*/
public static boolean magicFunctionImplementation(String permission, String permisionExpression) {
return false;
}
/**
* For formatting purpose
*/
public static String rightPad(String pad, int size) {
String paddedString = pad;
for (int i = pad.length(); i < size; i++) {
paddedString += " ";
}
return paddedString;
}
}
这是我的最后一个问题是可以用正则表达式编写这个函数吗?如果不可能有一种更优雅的方式来编写这个功能吗?
答案 0 :(得分:2)
我建议使用
public static boolean magicFunctionImplementation(String permission, String permissionExpression) {
boolean res = false;
String rx = permissionExpression.replace(".", "\\.") // escape the dot in regex
.replace("*", ".*") // prep the * token to match any 0+ chars
.replace("?", ".") // . will match any 1 char
.replaceAll("\\[([^\\]\\[]*)]", "($1)") // [a,b] => (a|b) = match a or b
.replaceAll("<([^<>]+)>", "(?:(?!$1)[^.])*") // <a,b> => (?:(?!a|b).)* = match text that is not a starting point of a or b
.replace(",", "|"); // replace all commas with alternation symbol (for the above 2 patterns)
if (permissionExpression.contains(permission)) { // if permissionExpr contains permission, it is TRUE
res = true;
} else {
res = permission.matches(rx); // Check if the entire permission matches the regex
}
return res;
}
请参阅Java demo