正则表达式找到所有起始大括号有一个结束括号

时间:2014-03-12 12:43:27

标签: php regex

我需要一个正则表达式来查找所有起始括号都有一个结束括号。 假设

([(([[(([]))]]))]) -- 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);

任何帮助请...

2 个答案:

答案 0 :(得分:1)

最简单的方法(在我看来)是实现堆栈数据结构并传递你的字符串。基本上是这样的:

  • 从左到右遍历字符串
  • 如果找到左括号,请将其添加到堆栈
  • else(你找到一个右括号)确保堆栈中最顶层的项目是相同类型的括号(所以如果找到},请确保堆栈中最顶层的项目是{)。这应该有助于你有这样的情况:({)}。如果匹配,则从堆栈中弹出。

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

答案 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('{[[()()]]}'));