如何在 java 中验证布尔字符串输入

How can I validate a boolean string input in java

提问人:Yisus 提问时间:10/29/2022 更新时间:10/30/2022 访问量:168

问:

我一直在与这个问题作斗争,还没有找到解决方案。我必须验证布尔字符串表达式的语法,以便我可以使用它来查找文档中的单词或句子。例如,(footballer football !| basket)( 应该是不正确的,因为 footballer 和 football 是分开的,应该在 “” 之间,也因为括号不正确和 ! |这没有意义。但是(“足球运动员足球”|!篮子)应该是正确的。这是一个简单的布尔表达式,所以我可以使用 &,!, |, ()... 有什么想法吗?

我试图遍历字符串,试图验证每个字符,但我无法得到最终的解决方案。

java 值 布尔逻辑 布尔值表达式

评论

1赞 Turing85 10/29/2022
看看上面的例子,看起来你必须写一个解析器。
0赞 tgdavies 10/29/2022
看看像 Lucene 这样的工具。

答:

0赞 DevilsHnd - 退した 10/30/2022 #1

这可能不是一个整体解决方案,但它可能会让您朝着该目标迈出一步。下面的方法将尝试解析和验证您在帖子中描述的提供的自定义表达式。如果提供的表达式有效,则在 String[] 数组中返回该表达式的组件。如果返回的 String[] 数组为 null,则发现提供的表达式无效。Invalid 表达式还将在控制台窗口中显示一条错误消息,解释该表达式无效的原因。请务必阅读代码中的注释:

/**
 * Custom Expression Parser/Validator:
 * 
 * If the supplied expression is valid whereas it meets the guidelines within 
 * the code, then return a String[] Array containing the components of that 
 * expression. If the expression is found to be invalid then a warning message 
 * is displayed to the Console Window explaining the problem and null is returned.
 * 
 * @param expressionString (String) The expression to validate.<br>
 * 
 * @return (String[] Array) Returns null if the expression is found invalid 
 * otherwise the returned String Array will contain the components of the 
 * expression. Process these returned expression components as you see fit.
 */
public String[] isExpressionValid(String expressionString) {
    // List to hold expression components.
    List<String> expressionList = new ArrayList<>();
    
    // If the expression string is null or empty then return null.
    if (expressionString == null || expressionString.isEmpty()) {
        return null;
    }
    
    // Are the brackets proper in the expression?
    Map<Character, Character> openClosePair = new HashMap<>();
    openClosePair.put(')', '(');
    Stack<Character> stack = new Stack<>();
    for (char ch : expressionString.toCharArray()) {
        if (openClosePair.containsKey(ch)) {
            if (stack.isEmpty() || !Objects.equals(stack.pop(), openClosePair.get(ch))) {
                break;
            }
        }
        else if (openClosePair.values().contains(ch)) {
            stack.push(ch);
        }
    }
    if (!stack.isEmpty()) {
        System.err.println("Invalid Expression! [" + expressionString + "] -  Parentheses Mismatch!");
        return null;
    }
    
    /* Parentheses are valid so now remove them to validate 
       the data within the parentheses.    */
    expressionString = expressionString.replaceAll("[\\(\\)]", "");
    
    /* Is &, !, or | within the expression? If so, is it proper?
       If there are consecutive `same` operators (ie: "&&&") then
       convert them to a single operator (ie: "&").        */
    expressionString = expressionString.replaceAll("[&]{2,}", "&")
            .replaceAll("[|]{2,}", "|"). replaceAll("[!]{2,}", "!");
    
    // Add whatever you feel would be invalid...
    String[] invalidOperators = {"&|", "|&", "!|", "!&", "!&|", "!|&", 
                                 "&!|", "&|!", "|!&", "|&!"};
    // Make sure of valid operator use.
    for (String op : invalidOperators) {
        if (expressionString.contains(op)) {
            System.err.println("Invalid Logical Operator Configuruation [" + 
                               op + "] Within Expression!");
            return null;
        }
    }
    
    /* Split the expression on delimiters '&' or '|' but 
       also add the delimiter to the generated array: */
    String regEx = "((?<=\\Q&\\E)|(?=\\Q&\\E))|"
                 + "((?<=\\Q|\\E)|(?=\\Q|\\E))";
    String[] expParts = expressionString.split(regEx);
    String exp;
    for (int i = 0; i < expParts.length; i++) {
        exp = expParts[i].trim();  // Remove leading/trailing whitespaces.
        // Is the element a non-numerical value?
        if (!exp.matches("-?\\d+(\\.\\d+)?") && !exp.matches("[!\\|&]")) {
            // This element must be alpha or alphanumeric. 
            /* Is there a whitespace in it? If so, is it wrapped in quote marks? 
               If not then this is invalid.                */
            if (exp.contains(" ") && ((!exp.startsWith("!\"") || !exp.startsWith("\"")) && !exp.endsWith("\""))) {
                System.err.println("Invalid String [" + exp + "] Within Expression!" 
                        + System.lineSeparator() + "Because this portion of the expression "
                        + "contains at least one whitespace," + System.lineSeparator() 
                        + "it should be wrapped within quotation marks excluding any Logical Operator" 
                        + System.lineSeparator() + "located at the beginning.");
                return null;
            }
        }
        /* Does the expression start with or end with a Logical Operator '&' or '|'? 
           This is considered invalid.            */
        if ((i == 0 || i == expParts.length - 1) && (exp.equals("&") || exp.equals("|"))) {
            System.err.println("Invalid Logical Operator Location! [" + expressionString + "]"
                        + System.lineSeparator() + "The expression can not start with or end "
                        + "with a '&' or '|' operator!");
            return null;        
        }
        
        // Add the expresion component to the List
        expressionList.add(exp);
    }
    
    // Convert the List to a String[] Array and return.
    return expressionList.toArray(new String[expressionList.size()]);
}

如何使用上述方法将如下所示:

String expression = "(footballer football !| basket)(";
    
String[] expressionParts = isExpressionValid(expression);

if (expressionParts != null) {
    // Display the components of the supplied expression:
    System.out.println(Arrays.toString(expressionParts));
}