3

Kinda of a noobie in PHP and Regex, I receive the following from a web service:

test:002005@1111@333333@;10205@2000@666666@;002005@1111@55555@;

The above line is a sequence of 3 numbers which repeats 3 times. I would like to get the 3rd number of each sequence and I believe the best course (besides 3000 explodes) would be preg_match_all but I am having a tough time wrapping my mind around RegEx.

The end result should look like this:

 Array
    (
        [0] => 333333
        [1] => 666666
        [2] => 55555
    )

Thanks in advance for any help.

5 Answers 5

5
if(preg_match_all('/.*?(?:\d+@){2}(\d+)@;/',$s,$m)) {
        print_r($m[1]);
}

http://ideone.com/99M9t

or

You can do it using explode as:

$input = rtrim($input,';');
$temp1 = explode(';',$input);
foreach($temp1 as $val1) {
        $temp2 = explode('@',$val1);
        $result[] = $temp2[2];
}
print_r($result);

http://ideone.com/VH29g

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot, that did the trick. I like this one due to defining the fact that there 2 "@XXXX" before the one that's needed. Great job!
2

Use the function explode()

<?php

$pizza  = "piece1@piece2@piece3@piece4@piece5@piece6";
$pieces = explode("@", $pizza);
echo $pieces[0]; // piece1
echo $pieces[1]; // piece2

?>

3 Comments

He asked for a version without explode, I assume his input is very large and he wants a fast/scalable solution. (I can't say anything on running times of either approach right now.)
@Taz: He asked for a version without 3000 explodes, I see only 1. this satisfies that requirement nicely I believe. Though this doesn't actually get the output he asked for...
I believe he needs another explode to get the third item in every $piece. That explode would be in a loop so you get n+1 explode calls.
0

I don't remember exactly how the saying goes but...

"You have a problem and decide to use regular expressions... now you have two problems."

Your problem can easily be solved if we assume 'test:' isn't part of the actual string to be parsed.

<?php

$in = '002005@1111@333333@;10205@2000@666666@;002005@1111@55555@;';

function splitGroupsAndGetColumn($input, $groupSeparator, $columnSeparator, $columnIndex, $skipEmpty=true)
{
    $result = array();

    $groups = explode($groupSeparator, $input);
    foreach($groups as $group)
    {
        $columns = explode($columnSeparator, $group);
        if (isset($columns[$columnIndex]))
        {
            array_push($result, $columns[$columnIndex]);
        }
        else if (! $skipEmpty)
        {
            array_push($result, NULL);
        }
    }

    return $result;
}

var_dump(splitGroupsAndGetColumn($in, ';', '@', 2));

Output:

array(3) {
  [0]=>
  string(6) "333333"
  [1]=>
  string(6) "666666"
  [2]=>
  string(5) "55555"
}

7 Comments

The saying must have come from somebody without knowledge of regular expressions ;-) ... at least: i wonder what makes someone think that loops are any better than regular expressions for such a simple task?
I dunno, but I like regexes almost as much as the original saying. regexes are fine IMHO but not to be used like the proverbial hammer.
I've seen a regexp in some book for validating e-mail addresses which spanned several pages. I think that would be a case where i would agree with you :-)
@harald: exactly. /([b]{2}|[^b]{2})/
@YagoRiveiro: indeed. also infinitely more readable if you ask me though.
|
0

You could use preg_match_all for this task, which makes the task quite simple:

$a = "test:002005@1111@333333@;10205@2000@666666@;002005@1111@55555@;";

preg_match_all('/@(\d+)@;/', $a, $m);

print_r($m);

$m[1] contains the output, you want.

Reference: http://php.net/manual/en/function.preg-match-all.php

Comments

0

My version :)

The regex (\d+) means I want all that is a number one or more

php > $a = '002005@1111@333333@;10205@2000@666666@;002005@1111@55555@';
php > preg_match_all('/(\d+)/',$a,$matches);
php > var_dump($matches);
array(2) {
  [0]=>
  array(9) {
    [0]=>
    string(6) "002005"
    [1]=>
    string(4) "1111"
    [2]=>
    string(6) "333333"
    [3]=>
    string(5) "10205"
    [4]=>
    string(4) "2000"
    [5]=>
    string(6) "666666"
    [6]=>
    string(6) "002005"
    [7]=>
    string(4) "1111"
    [8]=>
    string(5) "55555"
  }
  [1]=>
  array(9) {
    [0]=>
    string(6) "002005"
    [1]=>
    string(4) "1111"
    [2]=>
    string(6) "333333"
    [3]=>
    string(5) "10205"
    [4]=>
    string(4) "2000"
    [5]=>
    string(6) "666666"
    [6]=>
    string(6) "002005"
    [7]=>
    string(4) "1111"
    [8]=>
    string(5) "55555"
  }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.