Validating Crontab Entries with PHP

后端 未结 7 1142
青春惊慌失措
青春惊慌失措 2020-11-29 05:43

What is the best way to validate a crontab entry with PHP? Should I be using a regex, or an external library? I\'ve got a PHP script that adds/removes entries from a crontab

7条回答
  •  一向
    一向 (楼主)
    2020-11-29 06:08

    Thanks to Jordi Salvat i Alabart who posted great solution.

    I have only modified existing solution posted by Jordi Salvat i Alabart. It worked for me well, but I wanted to extract particular parts by capturing groups. I have added non-capturing parentheses to be able to extract particular parts of crontab record. It is easy to see which capture group to use when you test output regex at: http://www.regexplanet.com/advanced/java/index.html

    Salir.com.
     */
    
    function buildRegexp() {
        $numbers = array(
            'min' => '[0-5]?\d',
            'hour' => '[01]?\d|2[0-3]',
            'day' => '0?[1-9]|[12]\d|3[01]',
            'month' => '[1-9]|1[012]',
            'dow' => '[0-6]'
        );
    
        foreach ($numbers as $field => $number) {
            $range = "(?:$number)(?:-(?:$number)(?:\/\d+)?)?";
            $field_re[$field] = "\*(?:\/\d+)?|$range(?:,$range)*";
        }
    
        $field_re['month'].='|jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec';
        $field_re['dow'].='|mon|tue|wed|thu|fri|sat|sun';
    
        $fields_re = '(' . join(')\s+(', $field_re) . ')';
    
        $replacements = '@reboot|@yearly|@annually|@monthly|@weekly|@daily|@midnight|@hourly';
    
        return '^\s*(' .
                '$' .
                '|#' .
                '|\w+\s*=' .
                "|$fields_re\s+" .
                "|($replacements)\s+" .
                ')' .
                '([^\\s]+)\\s+' .
                '(.*)$';
    }
    

    This code generates regex:

    ^\s*($|#|\w+\s*=|(\*(?:\/\d+)?|(?:[0-5]?\d)(?:-(?:[0-5]?\d)(?:\/\d+)?)?(?:,(?:[0-5]?\d)(?:-(?:[0-5]?\d)(?:\/\d+)?)?)*)\s+(\*(?:\/\d+)?|(?:[01]?\d|2[0-3])(?:-(?:[01]?\d|2[0-3])(?:\/\d+)?)?(?:,(?:[01]?\d|2[0-3])(?:-(?:[01]?\d|2[0-3])(?:\/\d+)?)?)*)\s+(\*(?:\/\d+)?|(?:0?[1-9]|[12]\d|3[01])(?:-(?:0?[1-9]|[12]\d|3[01])(?:\/\d+)?)?(?:,(?:0?[1-9]|[12]\d|3[01])(?:-(?:0?[1-9]|[12]\d|3[01])(?:\/\d+)?)?)*)\s+(\*(?:\/\d+)?|(?:[1-9]|1[012])(?:-(?:[1-9]|1[012])(?:\/\d+)?)?(?:,(?:[1-9]|1[012])(?:-(?:[1-9]|1[012])(?:\/\d+)?)?)*|jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\s+(\*(?:\/\d+)?|(?:[0-6])(?:-(?:[0-6])(?:\/\d+)?)?(?:,(?:[0-6])(?:-(?:[0-6])(?:\/\d+)?)?)*|mon|tue|wed|thu|fri|sat|sun)\s+|(@reboot|@yearly|@annually|@monthly|@weekly|@daily|@midnight|@hourly)\s+)([^\s]+)\s+(.*)$
    

    Or Java alternative to generate this regex (without @X stuff):

    public static String buildRegex(){
        // numbers intervals and regex
        Map numbers = new HashMap();
        numbers.put("min", "[0-5]?\\d");
        numbers.put("hour", "[01]?\\d|2[0-3]");
        numbers.put("day", "0?[1-9]|[12]\\d|3[01]");
        numbers.put("month", "[1-9]|1[012]");
        numbers.put("dow", "[0-6]");
    
        Map field_re = new HashMap();
    
        // expand regex to contain different time specifiers
        for(String field : numbers.keySet()){
            String number = numbers.get(field);
            String range = "(?:"+number+")(?:-(?:"+number+")(?:\\/\\d+)?)?";
            field_re.put(field, "\\*(?:\\/\\d+)?|"+range+"(?:,"+range+")*");
        }
    
        // add string specifiers
        String monthRE = field_re.get("month");
        monthRE = monthRE + "|jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec";
        field_re.put("month", monthRE);
    
        String dowRE = field_re.get("dow");
        dowRE = dowRE + "|mon|tue|wed|thu|fri|sat|sun";
        field_re.put("dow", dowRE);
    
        StringBuilder fieldsReSB = new StringBuilder();
        fieldsReSB.append("^\\s*(")
                .append("$")
                .append("|#")
                .append("|\\w+\\s*=")
                .append("|");        
                .append("(")
                .append(field_re.get("min")).append(")\\s+(")
                .append(field_re.get("hour")).append(")\\s+(")
                .append(field_re.get("day")).append(")\\s+(")
                .append(field_re.get("month")).append(")\\s+(")
                .append(field_re.get("dow"))
                .append(")")
                .append("\\s+)")
                .append("([^\\s]+)\\s+")
                .append("(.*)$");
    
        return fieldsReSB.toString();
    }
    

提交回复
热议问题