mardi 8 septembre 2015

Best design: Regex builder/combiner

I have a code. which is part of an importer, that checks if an array has common criteria. For example: All elements are integers AND 5 characters long. For example $array=[12345,56789]

So there is an abstract Rule, and the different rules (ie: Length, Integer) extend the abstract rule:

<?php
/**
 * Abstract class that defines the rules
 * Date: 07.09.15
 * Time: 14:49
 */

namespace App\Tools\RegexExtract\Rules;


abstract class Rule
{

    const REGEX_POSITION_START    = 'start';
    const REGEX_POSITION_END      = 'end';
    const REGEX_POSITION_MIDDLE   = 'middle';

    protected $valid = true;

    abstract public function initialize($value);

    abstract public function check($value);

    abstract public function description();

    abstract public function getRegex();

    abstract public function getRegexPosition();

    public function isValid()
    {
        return $this->valid;
    }

}

Integer Rule Class

namespace App\Tools\RegexExtract\Rules;

class Integer extends Rule
{


    public function initialize($value)
    {
        return is_int($value);
    }

    public function check($value)
    {
        if (is_int($value) != true) {
            $this->valid = false;
        }
    }

    public function getRegex()
    {
        return '^\d';
    }

    public function getRegexPosition()
    {
        self::REGEX_POSITION_START;
    }

    public function description()
    {
        return 'only integer';
    }
}

My goal is to implement a goal that combines the rules, and generates a working Regex rule. I noticed this is not so easy...So for example the rule of "must have a specific length" would be

class Length extends Rule
{
...

    public function getRegex()
    {
        return '{'.$this->length.'}';
    }

.

 ....
}

That is why I am using the getRegexPosition method. But I am not sure this is the right path, if more rules come in, and they all share same position....What is best way to solve it, and get something at the end like

#is integer and has exactly length of 5
^\d{5}

Aucun commentaire:

Enregistrer un commentaire