2

I need an regular expression to find all starting brace has an ending brace. Suppose

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

for this, I've tried below:-

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

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

any help please...

Ripa Saha
  • 2,532
  • 6
  • 27
  • 51

2 Answers2

1

The easiest way to do this (in my opinion) would be to implement a stack data structure and pass through your string. Essentially something like so:

  • Traverse the string left to right
  • If you find an opening parenthesis, add it to the stack
  • else (you find a closing parenthesis) make sure that the top most item in the stack is the same type of parenthesis (so make sure that if you found a }, the top most item in the stack is {). This should help scenarios where you have something like so: ({)}. If it matches, pop from the stack.

If you repeat the above operation throughout the entire string, you should end up with an empty stack. This would mean that you have managed to match all open parenthesis with a close parenthesis.

npinti
  • 51,780
  • 5
  • 72
  • 96
0

You can use this:

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

(?1) is a reference to the subpattern (not the matched content) in the capture group 1. Since I put it in the capture group 1 itself, I obtain a recursion.

I added anchors for the start ^ and the end $ of the string to be sure to check all the string.

Note: If you need to check a string that contains not only brackets, you can replace each (?1)* with:

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

Note 2: If you want that an empty string return true, you must replace the last quantifier + with *

Working example:

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('{[[()()]]}'));
Casimir et Hippolyte
  • 88,009
  • 5
  • 94
  • 125