Java,用于验证权限的字符串匹配

时间:2016-11-19 13:30:05

标签: java regex string validation

您好我正在研究一种验证权限的算法, 权限由一系列由句点连接的标记定义, 例如:

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;
    }
}

这是我的最后一个问题是可以用正则表达式编写这个函数吗?如果不可能有一种更优雅的方式来编写这个功能吗?

1 个答案:

答案 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