Reputation: 54729
Ok, so I tried searching around first but I didn't exactly know how to word this question or a search phrase. Let me explain.
I have data that looks like this:
<!-- data:start -->
<!-- 0:start -->
<!-- 0:start -->0,9<!-- 0:stop -->
<!-- 1:start -->0,0<!-- 1:stop -->
<!-- 2:start -->9,0<!-- 2:stop -->
<!-- 3:start -->9,9<!-- 3:stop -->
<!-- 4:start -->0,9<!-- 4:stop -->
<!-- 0:stop -->
<!-- 1:start -->
<!-- 0:start -->1,5<!-- 0:stop -->
<!-- 1:start -->1,6<!-- 1:stop -->
<!-- 2:start -->3,6<!-- 2:stop -->
<!-- 3:start -->3,8<!-- 3:stop -->
<!-- 4:start -->4,8<!-- 4:stop -->
<!-- 1:stop -->
<!-- 2:start -->
<!-- 0:start -->0,7<!-- 0:stop -->
<!-- 1:start -->1,7<!-- 1:stop -->
<!-- 2:stop -->
<!-- data:stop -->
So it's basically a bunch of points. Here is the code I'm currently using to try and parse it so that it would create an array like so:
Array (
0 => Array (
0 => "0,9",
1 => "0,0",
2 => "9,0",
3 => "9,9",
4 => "0,9"
),
1 => Array (
0 => "1,5",
1 => "1,6",
2 => "3,6",
3 => "3,8",
4 => "4,8"
),
2 => Array (
0 => "0,7",
1 => "1,7"
)
)
However, it is returning an array that looks like this:
Array (
0 => "0,9",
1 => "0,0",
2 => "9,0"
)
Viewing the larger array that I have on my screen, you see that it's setting the first instance of that variable when matching. So how do I get it to find the widest match first and then process the insides. Here is the function I am currently using:
function explosion($text) {
$number = preg_match_all("/(<!-- ([\w]+):start -->)\n?(.*?)\n?(<!-- \\2:stop -->)/s", $text, $matches, PREG_SET_ORDER);
if ($number == 0) return $text;
else unset($item);
foreach ($matches as $item) if (empty($data[$item[2]])) $data[$item[2]] = $this->explosion($item[3]);
return $data;
}
I'm sure it will be something stupid and simple that I've overlooked, but that just makes it an easy answer for you I suppose.
EDIT: Here is a full output log of the entire data set that I took this sample from. The tags are printed out (replace them with > and <) and it's all inside a giant <code></code>
element for easy reading.
Here is the part that's messing up:
Array ( [0] => <!-- 0:start --> <!-- 0:start -->0,9<!-- 0:stop --> [1] => 0 [2] => <!-- 0:start -->0,9 )
0 => <!-- 0:start -->0,9
So it's stopping at the first occurrence of the stop tag for another piece inside of it. Should I be thinking the opposite direction and processing the smallest pieces first, replacing those so it won't interrupt the larger pieces, and then processing the larger pieces?
Upvotes: 0
Views: 242
Reputation: 5473
Well this works for me:
function explosion($text) {
$number = preg_match_all('/<(.*?)>(.+?)[<]/s', $text, $matches);
if ($number == 0) return $text;
$temp = array();
$data = array();
foreach($matches[2] as $coords){
if(trim($coords)==""){
if(!empty($temp)){
$data[] = $temp;
$temp = array();
}
}else{
$temp[] = $coords;
}
}
return $data;
}
The problem with your code was that it was picking up the subtags and the tagged values. Of course it would be hidden when printed in browser, so try taking a log of it for debugging purpose.
Upvotes: 1
Reputation: 3750
Here you go:
function explosion($text) {
preg_match_all("/<!-- ([\d]+):start -->(.+?)<!-- .*:stop -->/", $text, $matches, PREG_SET_ORDER);
$return = array();
foreach($matches as $match) {
if($match[1]==0) {
$return[] = array();
}
$return[count($return)-1][] = $match[2];
}
return $return;
}
Upvotes: 2