Page 1 of 1

Regex problem need to capture multiple items

Posted: Tue Feb 09, 2010 11:17 pm
by dreamline
Hi All,
It's been a while since my last post where I wanted to know how to capture everything out and insdie the parenthesis: mytest(1234). The option preg_split worked that time, but now I have another problem. Now I have multiple options generated like this: mytest(1234).mytest2(456).mytest3(8) and I first want to split everything on the . and then split everything outside and inside the parenthesis. I hope this can be done through preg_match_all.

Hope someone can help me on this one.

Thanks for any help. :)

Re: Regex problem need to capture multiple items

Posted: Wed Feb 10, 2010 6:27 am
by klevis miho
You can do a preg_match_all like this:

preg_match_all('#\((.+?) \)#s', $string, $matches);
print_r($matches);

without splitting the string with the '.' .

If you want to split it you can use a explode('.', $string); then a preg_match inside a foreach loop that loops the exploded string

Re: Regex problem need to capture multiple items

Posted: Wed Feb 10, 2010 8:13 am
by dreamline
Thanks Klevis,
I was already thinking about that. I had hoped it was possible to this in regex (in just 1 time), so I only have to loop through the matches once and process each item. With the explode explode I will have to do a loop inside a loop to be able to process all. It works ofcourse and I guess it would be the easier option. I have tried some things on only using the preg_match_all, came very close, but not completely.

Anyways thanks for your help and I will use the explode option and preg_match_all option. :)

Re: Regex problem need to capture multiple items

Posted: Wed Feb 10, 2010 9:09 am
by klevis miho
As you wish :)

Re: Regex problem need to capture multiple items

Posted: Wed Feb 10, 2010 9:09 pm
by dreamline
Hi,
i've been fiddling a bit and am coming close, however I just miss the finishing touch. Here's the regex and result that I have sofar. As you can see it splits almost correctly, but I'm missing the first character of test1, test2 and test3. The rest is OK. Hope some can show me the finishing touch and i'm happy as a little boy.. :)

I think I've got it. :)

<code>
preg_match_all('#[^\.](.*?)([\(](.*?)([$\)]))#i',$test,$options,PREG_SET_ORDER);

Result:
Array (
[0] => Array ( [0] => test1(2,3,4) [1] => est1 [2] => (2,3,4) [3] => 2,3,4 [4] => ) )
[1] => Array ( [0] => test2(12333) [1] => est2 [2] => (12333) [3] => 12333 [4] => ) )
[2] => Array ( [0] => test3(8) [1] => est3 [2] => (8) [3] => 8 [4] => ) )
)

Final code which is my opionion correct:
$test = 'test1(2,3,4).test2(12333).test3(8)';
preg_match_all('#([^\.].*?(?<!\.))([\(](.*?)([$\)]))#i',$test,$options,PREG_SET_ORDER);
print_r($options);
Result:
Array (
[0] => Array ( [0] => test1(2,3,4) [1] => test1 [2] => (2,3,4) [3] => 2,3,4 [4] => ) )
[1] => Array ( [0] => test2(12333) [1] => test2 [2] => (12333) [3] => 12333 [4] => ) )
[2] => Array ( [0] => test3(8) [1] => test3 [2] => (8) [3] => 8 [4] => ) ) )
</code>

Re: Regex problem need to capture multiple items

Posted: Thu Feb 11, 2010 1:35 am
by klevis miho
With this regex you are getting just one test 3 times.
mytest(1234).mytest2(456).mytest3(8)
Try this:

'#mytest[0-9]+\([0-9]+\)\.#'

this should get a string that begins with mytest, has a number after it, then a ( then a number then a ) then a .

Re: Regex problem need to capture multiple items

Posted: Thu Feb 11, 2010 2:16 am
by dreamline
Hi Klevis,
Thanks for your remark. For example purposes I put mytest as the only option, but normally my string would consist of different names for mytest1, mytest2 or mytest3. Also between the parenthesis it wouldn't always be a number but it can be alphanumeric to. For instance that the string could become:
font(arial,12).padding(5,5,5,5).text('this is a test') etc. etc.

Next time I will make sure my examples will reflect real data that i'm working with. Thanks for your help though, it's greatly appreciated.

:)

Re: Regex problem need to capture multiple items

Posted: Thu Feb 11, 2010 2:59 am
by klevis miho
Ok lets say you have this string:
font(arial,12).padding(5,5,5,5).text('this is a test')

what do you want to get from this?

Re: Regex problem need to capture multiple items

Posted: Thu Feb 11, 2010 3:29 am
by dreamline
Hi Klevis,
If I have this string: title('this is a test').font(arial,12).padding(0,5).template(blackbox)
The example above is from a function of my template engine and those are the parameters I use as input to generate text/png. The text generated is then put inside a framework specified by a template I created. So I extract the information like title, font, padding, template and use the options I specified between the parenthesis to create the text, content and footer all withing the template called blackbox. It's a bit hard to explain on what it exactly looks like but I can specify a single line within my template engine while PHP generates the rest based on the options I provided, or skip options when I didn't specify them.

In the above case I load a template called blackbox and set the title to 'this is a test' with font arial of 12 pixels/points (a png/ttf image), then I add a html text padding with 0 5px. That's basically the idea. Use 1 template to create multiple blackboxes on my screen with various options.

:)

Re: Regex problem need to capture multiple items

Posted: Thu Feb 11, 2010 3:54 am
by klevis miho
But you can do a simple preg_match_all to get just the things inside the parenthesis, or not?

Re: Regex problem need to capture multiple items

Posted: Thu Feb 11, 2010 5:32 am
by dreamline
Hi,
That's true, but the class I've written performs a few functions based on what's in front of the parenthesis and what's inside, that's why I wanted a preg_match_all to split the option from the parameter. :)

Re: Regex problem need to capture multiple items

Posted: Thu Feb 11, 2010 5:50 am
by klevis miho
:)

Ok just tell me what do you want to extract from this:
font(arial,12).padding(5,5,5,5).text('this is a test')

Just the output, simple

Re: Regex problem need to capture multiple items

Posted: Thu Feb 11, 2010 6:33 am
by dreamline
Hi,
Well here's what I have in mind when extracting from: font(arial,12).padding(5,5,5,5).text('this is a test'):
An array should be created with the following items:

[0][0] = font
[0][1] = arial,12

[1][0] = padding
[1][1] = 5,5,5,5

[2][0] = text
[2][1] = this is a test

This is basically the idea and the preg_match_all function I posted earlier is working, maybe it's not the most nice solution since it generates more items in the array than I need, but thats probably because of the regex expression (preg_match_all('#([^\.].*?(?<!\.))([\(](.*?)([$\)]))#i',$test,$options,PREG_SET_ORDER);)

Re: Regex problem need to capture multiple items

Posted: Thu Feb 11, 2010 12:10 pm
by ridgerunner
Your regex is more complicated than it needs to be. This script:

Code: Select all

<?php
$contents = "font(arial,12).padding(5,5,5,5).text('this is a test')";
preg_match_all('/(\w++)\(([^()]++)\)/', $contents, $matches, PREG_SET_ORDER);
print_r($matches);
?>
Produces these results:

Code: Select all

Array
(
    [0] => Array
        (
            [0] => font(arial,12)
            [1] => font
            [2] => arial,12
        )
    [1] => Array
        (
            [0] => padding(5,5,5,5)
            [1] => padding
            [2] => 5,5,5,5
        )
    [2] => Array
        (
            [0] => text('this is a test')
            [1] => text
            [2] => 'this is a test'
        )
)
Hope this helps! :)

Re: Regex problem need to capture multiple items

Posted: Thu Feb 11, 2010 6:22 pm
by dreamline
Thanks very much ridgerunner. That's exactly what I need and it looks so much more clean code than I generated. I just started getting into RegEx and read some tutorials, but sometimes it's hard to grasp what you can do, but like they say practise makes perfect and your solution is way more clean. :)

Thanks again. :D