我使用TDD并且必须通过一组测试来实现新库:
public function providerEdgesParser()
{
return array(
array('.edges=(user)', false), // 0
array('edges=test', false),
array('another:chars', false),
array('pl-ouf', false),
array('test', array('test')),
array('lang,lang', array('lang', 'lang')), // 5
array('quest,ans', array('quest', 'ans')),
array('q.edges=(a)', array('q' => array('a'))),
array('e.edges=(lang,et.edges=(lang)),ans', array('e' => array('lang', 'et' => array('lang')), 'ans')),
);
}
这是一个PHPUnit提供程序。在每个数组中,第一个元素是我的函数的参数,第二个元素是我的函数必须返回的。 以下是我提出的这个功能:
public function edgesParser($urlEdges)
{
// Check if edges syntax is valid
if (!preg_match('#^((?:(?:[a-z]+(?:\.edges\=\(\1\))?)\,?)+)$#ui', $urlEdges)) {
throw new \Exception('Edges syntax is wrong');
}
// Then, use a recursive function to build the array
// ...
// ...
}
该正则表达式的唯一目的是检测$urlEdges
字符串中的错误语法,因为它是最终用户输入。之后,我将构建正确的数组返回。
然而,这个正则表达式似乎没有按照我想要的方式工作:两个最新的测试抛出异常。他们不应该。
我一直在寻找解决方案很长一段时间,但我无法看到正则表达式出错的地方。这是a graphical representation of the regex。如果引用组中的内容不能正常工作吗?或者我做了一个微不足道的错误,我疲惫的眼睛无法看到?
答案 0 :(得分:0)
@HamZa提出了答案。
\1
back reference匹配第1组中匹配的内容。
(?1)
recursive mask执行第1组的模式。
第二种选择是我需要的。因此,合适的正则表达式可以是:#^((?:(?:[a-z]+(?:\.edges\=\((?1)\))?)\,?)+)$#ui
(拆分here)。