[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( $operators = array(
'not', '!', '-', '+', 'not', '!', '-', '+',
'or', '||', '&&', 'and', '|', '^', '&', '==', '===', '!=', '!==', '<', '>', '>=', '<=', 'not in', 'in', '..', '+', '-', '~', '*', '/', '%', '**', 'or', '||', '&&', 'and', '|', '^', '&', '==', '===', '!=', '!==', '<', '>', '>=', '<=', 'not in', 'in', '..', '+', '-', '~', '*', '/', '%', '=~', '!~', '**',
); );
$operators = array_combine($operators, array_map('strlen', $operators)); $operators = array_combine($operators, array_map('strlen', $operators));

View File

@ -38,6 +38,18 @@ class BinaryNode extends Node
{ {
$operator = $this->attributes['operator']; $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])) { if (isset($this->functions[$operator])) {
$compiler $compiler
->raw(sprintf('%s(', $this->functions[$operator])) ->raw(sprintf('%s(', $this->functions[$operator]))
@ -124,6 +136,10 @@ class BinaryNode extends Node
return $left / $right; return $left / $right;
case '%': case '%':
return $left % $right; 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' => 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), '**' => 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(false, new BinaryNode('not in', new ConstantNode('a'), $array)),
array(array(1, 2, 3), new BinaryNode('..', new ConstantNode(1), new ConstantNode(3))), 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('!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('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]+$/'))),
); );
} }
} }