user15063
user15063

Reputation:

PHP Regex to match following string example

My subject looks like this:

[9] 20:30:40 [SUCCESS] s-a24:1337
2
8.87
4038047
35320
4002727
[10] 20:30:40 [SUCCESS] s-d28:1337
2
2.64
4038047
37363
4000684
[11] 20:30:40 [SUCCESS] s-b29:1337
2
0.56
4038047
33066
4004981
[66] 20:30:42 [FAILURE] s-b25:1337 Timed out, Killed by signal 9
2
1.16
4038047
35274
[67] 20:30:42 [FAILURE] s-b30:1337 Timed out, Killed by signal 9

I need to create a multi-dimentional array that will match

There could be anywhere from 0 to 5 rows (5 rows is SUCCESS)

I'm absolutely inept in regex

What I started with is this, it does not work.

preg_match_all("/\[[0-9]+\](.*?)\[[0-9]+\]/",$output,$array);

Upvotes: 0

Views: 270

Answers (5)

Toto
Toto

Reputation: 91415

How about:

$string = '[9] 20:30:40 [SUCCESS] s-a24:1337
2
8.87
4038047
35320
4002727
[10] 20:30:40 [SUCCESS] s-d28:1337
2
2.64
4038047
37363
4000684
[11] 20:30:40 [SUCCESS] s-b29:1337
2
0.56
4038047
33066
4004981
[66] 20:30:42 [FAILURE] s-b25:1337 Timed out, Killed by signal 9
2
1.16
4038047
35274
[67] 20:30:42 [FAILURE] s-b30:1337 Timed out, Killed by signal 9
';

preg_match_all("/\[.*?\[(SUCCESS|FAILURE)\]\s+([^:]+):[^\n]+\n(?:([^[]+?)\n)?(?:([^[]+?)\n)?(?:([^[]+?)\n)?(?:([^[]+?)\n)?(?:([^[]+?)\n)?/m", $string, $matches, PREG_SET_ORDER);
print_r($matches);

output:

Array
(
    [0] => Array
        (
            [0] => [9] 20:30:40 [SUCCESS] s-a24:1337
2
8.87
4038047
35320
4002727

            [1] => SUCCESS
            [2] => s-a24
            [3] => 2
            [4] => 8.87
            [5] => 4038047
            [6] => 35320
            [7] => 4002727
        )

    [1] => Array
        (
            [0] => [10] 20:30:40 [SUCCESS] s-d28:1337
2
2.64
4038047
37363
4000684

            [1] => SUCCESS
            [2] => s-d28
            [3] => 2
            [4] => 2.64
            [5] => 4038047
            [6] => 37363
            [7] => 4000684
        )

    [2] => Array
        (
            [0] => [11] 20:30:40 [SUCCESS] s-b29:1337
2
0.56
4038047
33066
4004981

            [1] => SUCCESS
            [2] => s-b29
            [3] => 2
            [4] => 0.56
            [5] => 4038047
            [6] => 33066
            [7] => 4004981
        )

    [3] => Array
        (
            [0] => [66] 20:30:42 [FAILURE] s-b25:1337 Timed out, Killed by signal 9
2
1.16
4038047
35274

            [1] => FAILURE
            [2] => s-b25
            [3] => 2
            [4] => 1.16
            [5] => 4038047
            [6] => 35274
        )

    [4] => Array
        (
            [0] => [67] 20:30:42 [FAILURE] s-b30:1337 Timed out, Killed by signal 9

            [1] => FAILURE
            [2] => s-b30
        )

)

Upvotes: 0

Chris
Chris

Reputation: 7278

Quick and dirty, but it was fun to try:

$success_pattern = '/\[(SUCCESS|FAILURE)\]/';
preg_match_all($success_pattern, $subject, $success_matches);

$descriptor_pattern = '/\[(SUCCESS|FAILURE)\]\s(.+?):/';
preg_match_all($descriptor_pattern, $subject, $descriptor_matches);

$numbers_pattern = '/\[.*?\n((\d+\.{0,1}\d*\n)+)/';
preg_match_all($numbers_pattern, $subject, $numbers_matches);

$output = array();
for($x = 0; $x < count($success_matches[0]); $x++) {
    $output[] = array(
        'success' => $success_matches[1][$x],
        'descriptor' => $descriptor_matches[2][$x],
        'numbers' => explode("\n", trim($numbers_matches[1][$x]))
    );
}

Upvotes: 0

Jack
Jack

Reputation: 5768

(\[\d*\].*\[(SUCCESS|FAILURE)\]\s(s-.{3}).*(\r[\d\.]+){0,5})

http://regexr.com?30n45

This regex should work.

Upvotes: 0

John Conde
John Conde

Reputation: 219814

This works for me:

<?php

$str = '[9] 20:30:40 [SUCCESS] s-a24:1337
2
8.87
4038047
35320
4002727
[10] 20:30:40 [SUCCESS] s-d28:1337
2
2.64
4038047
37363
4000684
[11] 20:30:40 [SUCCESS] s-b29:1337
2
0.56
4038047
33066
4004981
[66] 20:30:42 [FAILURE] s-b25:1337 Timed out, Killed by signal 9
2
1.16
4038047
35274
[67] 20:30:42 [FAILURE] s-b30:1337 Timed out, Killed by signal 9';

preg_match_all("/^\[.*?\[(SUCCESS|FAILURE)\]\s(s\-\w\d{2}):1337.*?\n((.*\n){5})/m", $str, $matches, PREG_SET_ORDER);
//print_r($matches);
foreach ($matches as $match)
{
    echo $match[1] . "<br>\n";
    echo $match[2] . "<br>\n";
    echo $match[3] . "<br>\n";
}
?>

Upvotes: 0

Stefan Dochow
Stefan Dochow

Reputation: 1454

I am not sure a simple Regex is the way to go here, especially considering the variable count of data for each record.

So, what about splitting the string up?

By splitting it at every line break followed by a "[" and splitting each of the results at every line break you could evaluate each and every first line of a result with a simple regex and easily add the numerical data, if there is any.

Regards STEFAN

Upvotes: 2

Related Questions