有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java正则表达式验证器

我将从REST服务请求负载中获取where子句字符串(仅使用AND/OR运算符分隔的条件)。我想使用正则表达式验证输入字符串。每个条件将包含关键运算符值的个体

我在某种程度上努力做到这一点。我对REGEX不熟悉。我写了一些代码来验证这一点。但它部分起作用了。 有人能推荐正确的正则表达式吗?如果可能,请解释它是如何工作的。这很有帮助

所以我的问题是: 我的正则表达式正确吗?如果是,为什么matches()方法对第二个和第三个输入字符串返回false

为了使它在任何复杂字符串出现时都变得健壮,这个正则表达式会处理这个问题吗? 前任: “(用户名eq\'bjensen\'和familyName co\'O'Malley\”)或(用户名eq\'bjensen\'或familyName co\'O'Malley\”)

我正在粘贴我的代码片段

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class DummyTester {
    public DummyTester() {
        super();
    }

    public static void main(String[] args) {

        checkRegex("userName eq \"bjensen\"");  // returning Matches True
        checkRegex("(userName eq \"bjensen\" and familyName co \"O'Malley\")"); // returning matches False
        checkRegex("(userName eq \"bjensen\" and familyName co \"O'Malley\" AND userName eq \"bjensen\" AND familyName co \"O'Malley\")"); // returning matches False

    }

    static String checkRegex(String tester) {

        String regex ="(\\w[\\w\\d]* \\s*(?:co|eq|gt)\\s* \\\"\\w[\\w\\d\\-\\:\\']*\\\")* ?(?:and|or|AND|OR)?";
        System.out.println("The input rgex  sis : "+regex);
        System.out.println("The input String sis : "+tester);
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(tester);
        boolean b = m.matches(); 
        System.out.println("matcher is   : "+ b);
        while (m.find()) {
            System.out.println(m.group());
        }
        return null;
    }

}

下面是上述代码段的输出

输出:

输入rgex sis:(\w[\w\d]*\s*(?:co | eq | gt)\s*\“\w[\w\d-:\']\”?(?:和|或|和|或)

输入字符串sis:userName eq“bjensen”

matcher是真的

输入字符串sis:(userName eq“bjensen”和familyName co“O'Malley”)

匹配者是:假

用户名eq“bjensen”和

familyName公司“O'Malley”

输入字符串sis:(用户名eq“bjensen”和familyName co“O'Malley”以及用户名eq“bjensen”和familyName co“O'Malley”)

匹配者是:假

用户名eq“bjensen”和

familyName公司“O'Malley”和

用户名eq“bjensen”和

familyName公司“O'Malley”

谢谢,维杰


共 (1) 个答案

  1. # 1 楼答案

    matches()函数尝试将整个输入正则表达式与您的输入进行匹配。您的正则表达式正在寻找:

    [name] [operator] [string] [optional and-or]
    

    因此,当您的输入具有多个条件,例如:"(userName eq \"bjensen\" and familyName co \"O'Malley\")"时,正则表达式将不匹配整个输入,而只匹配第一个and。但第一个测试字符串,即"userName eq \"bjensen\""并非如此

    因此,您的代码需要:

        boolean b = m.matches();
        System.out.println("matcher is   : "+ b);
        if (b) { // we have a complete match
            System.out.println(m.group());
        }
        else {
            while (m.find()) {
                System.out.println(m.group());
            }
        }
    

    但是有一些事情可以用正则表达式来改进。首先,按照您定义它的方式,它将接受为有效输入:

    userName eq "bjensen" and

    。。。它有一个“悬挂”和

    如果您假定输入总是正确的,并且不需要验证输入,则这可能不是问题。但我建议对regex进行修改,不允许使用上述字符串。此外,字符类\w实际上相当于[A-Za-z0-9_]。您正在尝试将名称与以下内容匹配:

    \w[\w\d]*
    

    但是\w已经包含了所有的数字。我猜你真正想说的是,第一个字符必须是字母字符,后面的字符可以是字母数字。表达这一点的方式是:

    [a-z][a-z0-9]*
    

    为什么我没有包括范围A-Z?因为我将为带有(?i)的正则表达式设置不区分大小写的标志。这也意味着我可以简化不同操作符的测试,不必同时测试orOR

    您还将转义许多不需要转义的反斜杠字符,例如分号

    最后的正则表达式是:

    (?i)               # Turn on case-insensitive flag
    [a-z][a-z0-9]*     # Match alpha followed by 0 or more alphanumeric characters
    \s+                # Match one or more white space characters
    (?:co|eq|gt)       # Match "co" or "eq" or "gt"
    \s*                # Match 0 or more white space characters
    "                  # Match a double quote
    [^"]*              # Match 0 or more non-double quote characters
    "                  # Match a double quote
    (?:                # Start of a non-capturing group
        \s+            # Match one or more white space characters
        (?:and|or)     # Match "and" or "or"
        \s+            # Match one or more white space characters
        [a-z][a-z0-9]* # Match a name as before
        \s+            # Match 1 or more white space characters
        (?:co|eq|gt)   # Match an operator as before
        \s*            # Match 0 or more white space characters
        "[^"]*"        # Match a string as before
    )*                 # Optional non-capturing group repeated 0 or more times
    

    Regex demo

    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    public class DummyTester {
        public DummyTester() {
            super();
        }
    
        public static void main(String[] args) {
    
            checkRegex("userName eq \"bjensen\"");  // returning Matches True
            checkRegex("(userName eq \"bjensen\" and familyName co \"O'Malley\")"); // returning matches False
            checkRegex("(userName eq \"bjensen\" and familyName co \"O'Malley\" AND userName eq \"bjensen\" AND familyName co \"O'Malley\")"); // returning matches False
    
        }
    
        static String checkRegex(String tester) {
    
            String regex ="(?i)[a-z][a-z0-9]*\\s+(?:co|eq|gt)\\s*\"[^\"]*\"(?:\\s+(?:and|or)\\s+[a-z][a-z0-9]*\\s+(?:co|eq|gt)\\s*\"[^\"]*\")*";
            System.out.println("The input regex  sis : "+regex);
            System.out.println("The input String sis : "+tester);
            Pattern p = Pattern.compile(regex);
            Matcher m = p.matcher(tester);
            boolean b = m.find();
            System.out.println("finder is   : "+ b);
            if (b) {
                String s = m.group();
                System.out.println(s);
                return s;
            }
            return null;
        }
    
    }
    

    印刷品:

    The input regex  sis : (?i)[a-z][a-z0-9]*\s+(?:co|eq|gt)\s*"[^"]*"(?:\s+(?:and|or)\s+[a-z][a-z0-9]*\s+(?:co|eq|gt)\s*"[^"]*"*)
    The input String sis : userName eq "bjensen"
    finder is   : true
    userName eq "bjensen"
    The input regex  sis : (?i)([a-z][a-z0-9]*\s+(?:co|eq|gt)\s*"[^"]*"(?:\s+(?:and|or)\s+[a-z][a-z0-9]*\s+(?:co|eq|gt)\s*"[^"]*")*)
    The input String sis : (userName eq "bjensen" and familyName co "O'Malley")
    finder is   : true
    userName eq "bjensen" and familyName co "O'Malley"
    The input regex  sis : (?i)([a-z][a-z0-9]*\s+(?:co|eq|gt)\s*"[^"]*"(?:\s+(?:and|or)\s+[a-z][a-z0-9]*\s+(?:co|eq|gt)\s*"[^"]*")*)
    The input String sis : (userName eq "bjensen" and familyName co "O'Malley" AND userName eq "bjensen" AND familyName co "O'Malley")
    finder is   : true
    userName eq "bjensen" and familyName co "O'Malley" AND userName eq "bjensen" AND familyName co "O'Malley"
    

    Java demo