0

I have a function which basically retrieves the product id in a description.

private function scanForProductIdInDescription($string, $start, $end) {
        $startpos = strpos($string, $start) + strlen($start);
        if (strpos($string, $start) !== false) {
            $endpos = strpos($string, $end, $startpos);
            if (strpos($string, $end, $startpos) !== false) {
                return substr($string, $startpos, $endpos - $startpos);
            }
        }
    }

i use it as follows:

$from = "{PID =";
 $end = "}";
$description = 'some text {PID =340}  {PID =357}';
 $product_id = $this->scanForProductIdInDescription($description, $from, $end);

at the moment, it only gets the first occurence in the string. I need to find all occurences in the string. The result should be: $product_id = 340,357;

thanks

Rotimi
  • 4,783
  • 4
  • 18
  • 27

5 Answers5

3

Using a regular expression instead of strpos() is going to be you best bet. I've quickly put the following together which works with your example;

\{PID\s=([0-9]*)\}

You can see a working version here

Use of this in PHP would look like;

$re = '/\{PID\s=([0-9]*)\}/';
$str = 'some text {PID =340}  {PID =357}';

preg_match_all($re, $str, $matches);

// Print the entire match result
print_r($matches);

Edit: Edited to return only the actual ID in the matched string. IMO - this is a better solution than the other 2 answers posted as it returns ID's of any length, and only returns ID's matched in the format you've provided.

I've also updated my working example.

Tom
  • 4,257
  • 6
  • 33
  • 49
1

You can use preg_match_all:

$description = 'some text {PID =340}  {PID =357}';

preg_match_all('/=([0-9]+)\}/', $description, $matches);

var_dump($matches);

The result is:

array(2) {
  [0]=>
  array(2) {
    [0]=>
    string(5) "=340}"
    [1]=>
    string(5) "=357}"
  }
  [1]=>
  array(2) {
    [0]=>
    string(3) "340"
    [1]=>
    string(3) "357"
  }
}
Mihai Matei
  • 24,166
  • 5
  • 32
  • 50
1

You could use preg_match_all as followed:

<?php 


    // $sPattern = '^{PID\s=\d{3}}^';

    // by using a capture group "(" + ")" to enclose the number (\d), you can output just the numbers
    $sPattern = '{PID\s=(\d{3})}';

    $aOutput = array();
    $sString = 'some text {PID =340}  {PID =357}';

    preg_match_all($sPattern, $sString, $aOutput);

    // implode the first capture group to a string
    $aOutput = implode(",", $aOutput[1]);

    echo "<pre>";
    var_dump($aOutput);
?>

This will output:

string(7) "340,357"
atoms
  • 2,993
  • 2
  • 22
  • 43
1

To get the needed result(only PID numbers) - use the following approach:

$description = 'some text {PID =340}  {PID =357}';
preg_match_all("/(?<=\{PID =)\d+(?=\})/", $description, $matches);
$result = $matches[0];

print_r($result);

The output:

Array
(
    [0] => 340
    [1] => 357
)
RomanPerekhrest
  • 88,541
  • 4
  • 65
  • 105
  • worked like a charm! Thank you very much @roman. unforunately i cannot vote because i have a low reputation. Thanks again! – Rotimi Dec 23 '16 at 09:05
1

You can completely avoid the capture group, by using \K to restart the fullstring match before your desired numeric substrings.

Code: (Demo: https://3v4l.org/WalUc )

$description = 'some text {PID =340}  {PID =357}';
echo implode(',', preg_match_all('~\{PID =\K\d+~', $description, $out) ? $out[0] : []);

Output:

340,357

The benefits to this technique are:

  1. Fewer steps for the regex engine to make.
  2. No unnecessary bloat in the matches array ($out).
mickmackusa
  • 43,625
  • 12
  • 83
  • 136