Jump to content

[SOLVED] preg_match_all returns only one match


propellerhead

Recommended Posts

Hi.

 

I'm new with regular expressions so this may not be a big deal for you, but I'm stuck for hours on this bit and I can't find the solution. Here I go:

 

I have a string of this kind

 

<custom>
    probe1
    <custom>
        probe2
    </custom>
    probe3
</custom>
<custom>
    probe4
</custom>
<custom>
    probe5
</custom>

 

I'm trying to match only those custom tags that don't have child (custom) tags in them, so I use this regex

 

/<custom>((?!.*<custom>).*)<\/custom>/s

 

and so, it looks fine on first sight, but there is a problem. When I make the match using preg_match_all it onlly returns the last matching pattern

 

<custom>
    probe5
</custom>

 

here is the array dump using print_r

 

Array
(
    [0] => Array
        (
            [0] => <custom>
    probe5
</custom>
            [1] => 
    probe5

        )

)

 

How do I fix this? I know that there must be something wrong with the regex, but my knowledge in this field is limited and I can't find the solution.

 

Here is the whole code

 

<?php
$string = "
<custom>
    probe1
    <custom>
        probe2
    </custom>
    probe3
</custom>
<custom>
    probe4
</custom>
<custom>
    probe5
</custom>";

$regex = "/<custom>((?!.*<custom>).*)<\/custom>/s";

preg_match_all($regex, $string, $arry, PREG_SET_ORDER);
print_r($arry);

?>

 

I'd be very very thankful :)

try

<?php
$string = "
<custom>
    probe1
    <custom>
        probe2
    </custom>
    probe3
</custom>
<custom>
    probe4
</custom>
<custom>
    probe5
</custom>";

//$regex = "/<custom>((?!.*<custom>).*)<\/custom>/s";

//preg_match_all($regex, $string, $arry, PREG_SET_ORDER);
$a = explode('<custom>',$string);
foreach ($a as $b){
$b = explode('</custom>',$b);
if (count($b) > 1) $arry[] = $b[0];
}
print_r($arry);

?>f/code]

explode won't work because the <custom> tag is just for an example. The nature of the application requires it to be parsed using regular expression because the attributes that will be placed inside the custom tag <custom attr1="blah" attr2="blah">, and the large content.

Regular expressions are not the best tool for nested data, but this works:

 

<pre>
<?php

$data = <<<DATA
<custom>
    probe1
    <custom>
        probe2
    </custom>
    probe3
</custom>
<custom>
    probe4
</custom>
<custom>
    probe5
</custom>
DATA;

preg_match_all('%<custom>(??!<custom>)(?!</custom>).)*<\/custom>%s', $data, $matches);
print_r($matches);

?>
</pre>

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.