Dynadot โ€” .com Registration $8.99

Regular Expression Question

Spaceship Spaceship
Watch

evdoxos

Established Member
Impact
0
You know that math expressions may have many parentheses '(' and ')' and there are parentheses in other parentheses:

Code:
...(...(...(...)...(...)...(...(...(...)...)...(...)...)...)...)...
   [COLOR=Red]1[/COLOR]   2   3   2   3   2   3   4   5   4   3   4     3   2   1   [COLOR=Red]0[/COLOR]
I want to get all matches that start with '(' and finish with the corresponding ')'.
In the above example the match should be from 1 to 0.
Is there a regular expression -in PHP- that can do this?
 
Last edited:
0
•••
The views expressed on this page by users and staff are their own, not those of NamePros.
Unstoppable DomainsUnstoppable Domains
This one should work:

PHP:
$subj = "123(ab(cde)fg(ghijklmn)sdf)jerhk"; //test string
$pattern = "/\((.*)\)/"; //our regexp

if (preg_match($pattern, $subj, $matches))
	echo $matches[0];

After execution $matches[0] will contain "(ab(cde)fg(ghijklmn)sdf)" and $matches[1] -- "ab(cde)fg(ghijklmn)sdf" (without open and close parentheses)
 
0
•••
It dosn't work. Inserting one more parenthesis in your test string:

"123(ab(cde)fg(ghijklmn)s)df)jerhk"

We shoud take (ab(cde)fg(ghijklmn)s) but we take (ab(cde)fg(ghijklmn)s)df)

There is a solution for a similar problem but in Perl : http://perl.plover.com/yak/regex/samples/slide083.html
But I want in PHP.
 
0
•••
It will be possible to do but will not be easy imho.

I will have a look tomorrow see if I can come up with a regexp for it. Cant do it atm as had a few drinks.

On a side note however what was previously posted should do it. If the maths expression has mismatching parenthesis then it is an invalid expression
 
Last edited:
0
•••
Peter said:
On a side note however what was previously posted should do it. If the maths expression has mismatching parenthesis then it is an invalid expression
You are right.
I should give this example: 123(ab(cde)fg(ghijklmn)sdf)je(rh)k

The result then should be (ab(cde)fg(ghijklmn)sdf) but it is (ab(cde)fg(ghijklmn)sdf)je(rh)
 
0
•••
I apologize for my inattention to details...
So, if we have, for example, "ab(cd)ef(ghi(jkl)mn(o)prs)" string, then result should be "(cd)"?

And is it really necessary to perform this task with regexp?
 
0
•••
un4given[MAD] said:
And is it really necessary to perform this task with regexp?
Agreed. Probably not the best way to do this. Some string functions could do the job with less of a headache.

Solution: Have a loop. As you parse through the string, add 1 to an $open variable when you hit '(' and add one to $close when you hit ')'. When $open == $close you are in business and know the start and stop positions of the string to take.

Problem solved.
 
0
•••
un4given[MAD] said:
So, if we have, for example, "ab(cd)ef(ghi(jkl)mn(o)prs)" string, then result should be "(cd)"?
Yes it should be (cd)

MJ said:
Solution: Have a loop. As you parse through the string, add 1 to an $open variable when you hit '(' and add one to $close when you hit ')'. When $open == $close you are in business and know the start and stop positions of the string to take.Problem solved.
I'm looking for to match more complicated cases as:

alphaNumericFunctionName(...(...(...)...(...)...(...(...(...)...)...(...)...)...)...(...)...)

and using preg_replace_callback() to replace some things in it (speed is very important).
 
0
•••
Doing it with regular expressions is the right approach IMO but you need to use recursive backreferences as the number of nested parentheses is not fixed.

PHP:
<?php
$expr = "123(ab(cde)fg(ghijklmn)sdf)je(rh)k";
$pattern="/\(([^()]+|(?R))*\)/";
if (preg_match($pattern,$expr,$matches)) {
echo $matches[0];
}
?>

For this expression to work the parentheses must be nested properly.
 
0
•••
sdsinc said:
PHP:
$pattern="/\(([^()]+|(?R))*\)/";
Wow, that was really amazing!
Could you please, explain, what is (?R) in this expression?
 
0
•••
?R is a special pattern that performs a recursive substitution of the whole regular expression which allows unlimited nesting depth
 
0
•••
sdsinc said:
PHP:
"/\(([^()]+|(?R))*\)/"
You are GOD!!! It works perfectly!!!
 
0
•••
Dynadot โ€” .com Registration $8.99Dynadot โ€” .com Registration $8.99
Appraise.net
Unstoppable Domains
Domain Recover
DomainEasy โ€” Live Options
  • The sidebar remains visible by scrolling at a speed relative to the pageโ€™s height.
Back