2014-03-12 151 views
2

我需要一个正则表达式来查找所有起始大括号的末尾大括号。 假设正则表达式查找所有起始大括号的末尾大括号

([(([[(([]))]]))]) -- this one will return true. but 
[](()()[[]])[][[([]) --- this one will return false 

对于这一点,我已经试过如下: -

function check($str) { 
    $output = ""; 
    $pattern = "/(\{[^}]*)([^{]*\})/im"; 
    preg_match($pattern, $str, $match); 
    print_r($match[0]); 
} 

assert(check("[](()()[[]])[][[([])") === FALSE); 

任何帮助,请...

+1

标准定期EXPRES sions不能这样做,因为他们不能计数或递归。 Perl有一个递归扩展,可以做到这一点,但PHP使用PCRE,而不是。 – Barmar

+0

如果我理解的很好,如果括号不平衡,你想获得假?应该')('返回'true'? –

+0

[正则表达式匹配嵌套大括号]可能的重复(http://stackoverflow.com/questions/2778532/regular-expression-to-match-nested-braces) – Barmar

回答

1

做到这一点(在我看来)最简单的方法是实现一个堆栈数据结构并传递你的字符串。本质的东西,像这样:

  • 遍历字符串左如果你发现一个左括号向右
  • ,将其添加到堆栈
  • 否则(你找到一个右括号)确保最顶端项在堆栈中是相同类型的括号(因此请确保如果您发现},堆栈中最顶端的项目是{)。这应该有助于你有这样的情景:({)}。如果匹配,从堆栈弹出。

如果您在整个字符串中重复上述操作,您应该最终得到一个空的堆栈。这意味着您已经设法将所有左括号与右括号匹配。

0

您可以使用此:

$pattern = '~^(\((?1)*\)|\[(?1)*]|{(?1)*})+$~'; 

(?1)是捕获组1。因为我把它捕获组1本身在该子模式的引用(不匹配的内容),我得到一个递归。

我加了锚为开始^和结尾$的字符串,一定要检查所有的字符串。

注意:如果你需要检查不仅包括括号中的字符串,可以相互替换(?1)*有:

(?>[^][}{)(]++|(?1))* 

注2:如果你想有一个空字符串返回true,则必须更换最后量词+*

工作例如:

function check($str, $display = false) { 
    if (preg_match('~^(\((?1)*\)|\[(?1)*]|{(?1)*})+$~', $str, $match)) { 
     if ($display) echo $match[0]; 
     return true; 
    } 
    elseif (preg_last_error() == PREG_RECURSION_LIMIT_ERROR) { 
     if ($display) echo "The recursion limit has been reached\n"; 
     return -1; 
    } else return false; 
} 

assert(check(')))') === false); 

check('{[[()()]]}', true); 

var_dump(check('{[[()()]]}')); 
相关问题