Dynadot Aftermarket: discover domain gems worth investing in. Visit our aftermarket.

Regular Expression Question

Namecheap AuctionsNamecheap Auctions
SpaceshipSpaceship
SpaceshipSpaceship
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
Close
The views expressed on this page by users and staff are their own, not those of NamePros.
GoDaddyGoDaddy
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
Close
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
Close
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
Close
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
Close
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
Close
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
Close
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
Close
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
Close
sdsinc said:
PHP:
$pattern="/\(([^()]+|(?R))*\)/";
Wow, that was really amazing!
Could you please, explain, what is (?R) in this expression?
 
0
Close
?R is a special pattern that performs a recursive substitution of the whole regular expression which allows unlimited nesting depth
 
0
Close
sdsinc said:
PHP:
"/\(([^()]+|(?R))*\)/"
You are GOD!!! It works perfectly!!!
 
0
Close
AIVikingsAIVikings

We're social

Escrow.com
Spaceship
Domain Recover
CryptoExchange.com

NamePros updates

Switch between accounts
You can now stay logged in to more than one NamePros account in the same browser. Click your avatar, then "Accounts in this browser", to...
AIVikings
Catchy
  • The sidebar remains visible by scrolling at a speed relative to the page’s height.
Back