Add Regexp Rule to ValidatorChain

@param string      $expression
@param string|null $description

@return ValidatorChain
@throws \Bluz\Validator\Exception\ComponentException
176492
public function regexp($expression, $description = null): ValidatorChain
    {
        $rule = Validator::rule('regexp', [$expression]);
        if (null !== $description) {
            $rule->setDescription($description);
        }
        $this->addRule($rule);
        return $this;
    }
644517
protected static function convertNthExpression($expression)
    {
        if ($expression === '') {
            throw new InvalidSelectorException('nth-child (or nth-last-child) expression must not be empty');
        }

        if ($expression === 'odd') {
            return 'position() mod 2 = 1 and position() >= 1';
        }

        if ($expression === 'even') {
            return 'position() mod 2 = 0 and position() >= 0';
        }

        if (is_numeric($expression)) {
            return sprintf('position() = %d', $expression);
        }

        if (preg_match("/^(?P<mul>[0-9]?n)(?:(?P<sign>\+|\-)(?P<pos>[0-9]+))?$/is", $expression, $segments)) {
            if (isset($segments['mul'])) {
                $multiplier = $segments['mul'] === 'n' ? 1 : trim($segments['mul'], 'n');
                $sign = (isset($segments['sign']) && $segments['sign'] === '+') ? '-' : '+';
                $position = isset($segments['pos']) ? $segments['pos'] : 0;

                return sprintf('(position() %s %d) mod %d = 0 and position() >= %d', $sign, $position, $multiplier, $position);
            }
        }

        throw new InvalidSelectorException(sprintf('Invalid nth-child expression "%s"', $expression));
    }
1171202
private function validate($scheme): ?string
    {
        $scheme = $this->filterComponent($scheme);
        if (null === $scheme) {
            return $scheme;
        }

        if (1 === preg_match(self::REGEXP_SCHEME, $scheme)) {
            return strtolower($scheme);
        }

        throw new SyntaxError(sprintf("The scheme '%s' is invalid", $scheme));
    }
765084
public function parse(string $expression): Interval
    {
        $parse = \explode(',', $expression);
        if (self::BOUNDARIES !== count($parse)) {
            throw new \ErrorException('Parse interval expression');
        }

        $startTerm = \reset($parse);
        $endTerm   = \end($parse);

        $startTerm = $this->parseStartTerm($startTerm);
        $endTerm   = $this->parseEndTerm($endTerm);

        return new Interval(
            $startTerm,
            $endTerm
        );
    }
445795
public function setSubscriptionDescription($description)
    {
        if (strlen($description) > 100) {
            throw new InvalidArgumentException("Subscription description cannot be longer than 100 characters");
        }
        if (preg_match('/[^a-zA-Z0-9_ -]/', $description)) {
            throw new InvalidArgumentException("Subscription description cannot contain special characters");
        }
        $this->parameters['sub_com'] = $description;
    }
597941
public static String strip(final String expression) {
        final String expr = StringUtils.trimToEmpty(expression);
        final Matcher matcher = DELIMITED_EXPR.matcher(expr);
        return matcher.matches() ? matcher.group(1) : expr;
    }
61876
protected function parseSegments( $expression, $requiredSegmentCount )
	{
		$segments = explode( ',', preg_replace( "/[ \(\)\\\"\']/", '', $expression ) );

		if ( $requiredSegmentCount > count( $segments ) )
			throw new FrameworkException( "Blade directive is short the required number of segments of " . $requiredSegmentCount );

		return $segments;
	}
1283304
public static Expression regexpPosition(String expression, String pattern) {
        return regexpPosition(x(expression), pattern);
    }
965574
public function xpathQuery(string $expression, \DOMNode $context_node=null)
    {
        if ($this->dom_xpath) {
            $node_list = $this->dom_xpath->query($expression, $context_node);

            if ($node_list instanceof \DOMNodeList) {
                return $node_list;
            } elseif ($node_list === false && $context_node) {
                throw new \Exception('Expression '.$expression.' is malformed or contextnode is invalid.');
            } elseif ($node_list === false) {
                throw new \Exception('Expression '.$expression.' is malformed.');
            }
        }

        return false;
    }
721302
public function filter( $expression ) {
		$this->expressionValidator->validate( $expression, ExpressionValidator::VALIDATE_FUNCTION );

		$this->usageValidator->trackUsedPrefixes( $expression );
		$this->usageValidator->trackUsedVariables( $expression );

		$this->filters[] = '(' . $expression . ')';

		return $this;
	}
847208
protected static function _tokenize($expression_src)
    {
        // Child selectors
        $expression = str_replace('>', '/', $expression_src);

        // IDs
        $expression = preg_replace('|#([a-z][a-z0-9_-]*)|i', "[@id='$1']", $expression);
        $expression = preg_replace('|(?<![a-z0-9_-])(\[@id=)|i', '*$1', $expression);

        // arbitrary attribute strict equality
        $expression = preg_replace_callback(
            '|\[@?([a-z0-9_-]*)([~\*\^\$\|\!])?=([^\[]+)\]|i',
            static function ($matches) {
                $attr = strtolower($matches[1]);
                $type = $matches[2];
                $val = trim($matches[3], "'\" \t");

                $field = ($attr === '' ? 'text()' : '@' . $attr);

                $items = [];
                foreach (explode(strpos($val, '|') !== false ? '|' : '&', $val) as $word) {
                    if ($type === '') {
                        $items[] = "$field='$word'";
                    } elseif ($type === '~') {
                        $items[] = "contains(concat(' ', normalize-space($field), ' '), ' $word ')";
                    } elseif ($type === '|') {
                        $item = "$field='$word' or starts-with($field,'$word-')";
                        $items[] = $word === $val ? $item : "($item)";
                    } elseif ($type === '!') {
                        $item = "not($field) or $field!='$word'";
                        $items[] = $word === $val ? $item : "($item)";
                    } else {
                        $items[] = ['*' => 'contains', '^' => 'starts-with', '$' => 'ends-with'][$type] . "($field, '$word')";
                    }
                }
                return '[' . implode(strpos($val, '|') !== false ? ' or ' : ' and ', $items) . ']';
            },
            $expression
        );

        //attribute contains specified content
        $expression = preg_replace_callback(
            '|\[(!?)([a-z][a-z0-9_-\|&]*)\]|i',
            static function ($matches) {
                $val = $matches[2];
                $op = strpos($val, '|') !== false ? '|' : '&';

                $items = [];
                foreach (explode($op, $val) as $word) {
                    $items[] = '@' . $word;
                }

                $r = '[' . implode($op === '|' ? ' or ' : ' and ', $items) . ']';
                return $matches[1] === '!' ? "not($r)" : $r;
            },
            $expression
        );
        // Classes
        if (false === strpos($expression, '[@')) {
            $expression = preg_replace(
                '|\.([a-z][a-z0-9_-]*)|i',
                "[contains(concat(' ', normalize-space(@class), ' '), ' \$1 ')]",
                $expression
            );
        }

        /** ZF-9764 -- remove double asterisk */
        $expression = str_replace('**', '*', $expression);

        return $expression;
    }
888789
protected function checkAttributeExpression(DOMNode $node, Tag $tag, $expr)
	{
		preg_match_all('(@([-\\w]+))', $expr, $matches);
		foreach ($matches[1] as $attrName)
		{
			$this->checkAttribute($node, $tag, $attrName);
		}
	}
988346
public function match($expression)
    {
        if (is_callable($expression)) {
            $expressionConfigurator = $expression;
            $expression = new Expression();
            call_user_func($expressionConfigurator, $expression);
        }

        if ($expression instanceof Expression) {
            $expression = $expression->toArray();
        } elseif (!is_array($expression)) {
            throw new Exception('Must be array, callable or instance of \Sokil\Mongo\Expression');
        }

        $this->addStage('$match', $expression);
        return $this;
    }
76751
public function setExpression($expression)
    {
        if (is_string($expression)) {
            $expression = CronExpression::factory($expression);
        }

        $this->expression = $expression;

        return $this;
    }
860881
public function extract($expression, $capture = 0) {
			$valid = (boolean)preg_match($expression, $this->value, $match);

			// Nothing to return:
			if ($valid === false || isset($match[$capture]) === false) {
				return null;
			}

			return $match[$capture];
		}
56760
protected function buildExpression(Expression $expression)
    {
        $template = $expression instanceof Subquery ? '(%s)' : '%s';
        $expressionString = $this->stringifyExpression($expression);
        
        return trim(sprintf($template, $expressionString));
    }
35917
public static function compile($expression, $type = self::TYPE_CSS)
    {
        if (!is_string($expression)) {
            throw new InvalidArgumentException(sprintf('%s expects parameter 1 to be string, %s given', __METHOD__, gettype($expression)));
        }

        if (!is_string($type)) {
            throw new InvalidArgumentException(sprintf('%s expects parameter 2 to be string, %s given', __METHOD__, gettype($type)));
        }

        if (strcasecmp($type, self::TYPE_XPATH) !== 0 && strcasecmp($type, self::TYPE_CSS) !== 0) {
            throw new RuntimeException(sprintf('Unknown expression type "%s"', $type));
        }

        $expression = trim($expression);

        if ($expression === '') {
            throw new InvalidSelectorException('The expression must not be empty');
        }

        if (strcasecmp($type, self::TYPE_XPATH) === 0) {
            return $expression;
        }

        if (!array_key_exists($expression, static::$compiled)) {
            static::$compiled[$expression] = static::cssToXpath($expression);
        }

        return static::$compiled[$expression];
    }