[ExpressionLanguage] added support for regexes

This commit is contained in:
Fabien Potencier 2013-09-03 09:29:01 +02:00
parent 9d98fa25ec
commit 3a41781640
4 changed files with 25 additions and 1 deletions

View File

@ -101,7 +101,7 @@ class Lexer
{
$operators = array(
'not', '!', '-', '+',
'or', '||', '&&', 'and', '|', '^', '&', '==', '===', '!=', '!==', '<', '>', '>=', '<=', 'not in', 'in', '..', '+', '-', '~', '*', '/', '%', '**',
'or', '||', '&&', 'and', '|', '^', '&', '==', '===', '!=', '!==', '<', '>', '>=', '<=', 'not in', 'in', '..', '+', '-', '~', '*', '/', '%', '=~', '!~', '**',
);
$operators = array_combine($operators, array_map('strlen', $operators));

View File

@ -38,6 +38,18 @@ class BinaryNode extends Node
{
$operator = $this->attributes['operator'];
if ('=~' == $operator || '!~' == $operator) {
$compiler
->raw(('!~' == $operator ? '!' : '').'preg_match(')
->compile($this->nodes['right'])
->raw(', ')
->compile($this->nodes['left'])
->raw(')')
;
return;
}
if (isset($this->functions[$operator])) {
$compiler
->raw(sprintf('%s(', $this->functions[$operator]))
@ -124,6 +136,10 @@ class BinaryNode extends Node
return $left / $right;
case '%':
return $left % $right;
case '=~':
return preg_match($right, $left);
case '!~':
return !preg_match($right, $left);
}
}
}

View File

@ -67,6 +67,8 @@ class Parser
'*' => array('precedence' => 60, 'associativity' => Parser::OPERATOR_LEFT),
'/' => array('precedence' => 60, 'associativity' => Parser::OPERATOR_LEFT),
'%' => array('precedence' => 60, 'associativity' => Parser::OPERATOR_LEFT),
'=~' => array('precedence' => 70, 'associativity' => Parser::OPERATOR_LEFT),
'!~' => array('precedence' => 70, 'associativity' => Parser::OPERATOR_LEFT),
'**' => array('precedence' => 200, 'associativity' => Parser::OPERATOR_RIGHT),
);
}

View File

@ -61,6 +61,9 @@ class BinaryNodeTest extends AbstractNodeTest
array(false, new BinaryNode('not in', new ConstantNode('a'), $array)),
array(array(1, 2, 3), new BinaryNode('..', new ConstantNode(1), new ConstantNode(3))),
array(1, new BinaryNode('=~', new ConstantNode('abc'), new ConstantNode('/^[a-z]+$/'))),
array(false, new BinaryNode('!~', new ConstantNode('abc'), new ConstantNode('/^[a-z]+$/'))),
);
}
@ -108,6 +111,9 @@ class BinaryNodeTest extends AbstractNodeTest
array('!in_array("a", array(0 => "a", 1 => "b"))', new BinaryNode('not in', new ConstantNode('a'), $array)),
array('range(1, 3)', new BinaryNode('..', new ConstantNode(1), new ConstantNode(3))),
array('preg_match("/^[a-z]+/i\$/", "abc")', new BinaryNode('=~', new ConstantNode('abc'), new ConstantNode('/^[a-z]+/i$/'))),
array('!preg_match("/^[a-z]+\$/", "abc")', new BinaryNode('!~', new ConstantNode('abc'), new ConstantNode('/^[a-z]+$/'))),
);
}
}