From 3a417816405906da17248aa9d413956831f2817e Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 3 Sep 2013 09:29:01 +0200 Subject: [PATCH] [ExpressionLanguage] added support for regexes --- .../Component/ExpressionLanguage/Lexer.php | 2 +- .../ExpressionLanguage/Node/BinaryNode.php | 16 ++++++++++++++++ .../Component/ExpressionLanguage/Parser.php | 2 ++ .../Tests/Node/BinaryNodeTest.php | 6 ++++++ 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/ExpressionLanguage/Lexer.php b/src/Symfony/Component/ExpressionLanguage/Lexer.php index 1c573e8f59..2aa32dda0c 100644 --- a/src/Symfony/Component/ExpressionLanguage/Lexer.php +++ b/src/Symfony/Component/ExpressionLanguage/Lexer.php @@ -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)); diff --git a/src/Symfony/Component/ExpressionLanguage/Node/BinaryNode.php b/src/Symfony/Component/ExpressionLanguage/Node/BinaryNode.php index 850376b50f..c2bd58df73 100644 --- a/src/Symfony/Component/ExpressionLanguage/Node/BinaryNode.php +++ b/src/Symfony/Component/ExpressionLanguage/Node/BinaryNode.php @@ -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); } } } diff --git a/src/Symfony/Component/ExpressionLanguage/Parser.php b/src/Symfony/Component/ExpressionLanguage/Parser.php index 6603dd42fc..f5eae2b455 100644 --- a/src/Symfony/Component/ExpressionLanguage/Parser.php +++ b/src/Symfony/Component/ExpressionLanguage/Parser.php @@ -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), ); } diff --git a/src/Symfony/Component/ExpressionLanguage/Tests/Node/BinaryNodeTest.php b/src/Symfony/Component/ExpressionLanguage/Tests/Node/BinaryNodeTest.php index ecf3c7728b..fb5389cb49 100644 --- a/src/Symfony/Component/ExpressionLanguage/Tests/Node/BinaryNodeTest.php +++ b/src/Symfony/Component/ExpressionLanguage/Tests/Node/BinaryNodeTest.php @@ -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]+$/'))), ); } }