Alex Watt
Alex Watt

Reputation: 937

php custom string to array with regex

I am trying to use regex in PHP to parse a string and make an array. Here is my attempt:

function parseItemName($itemname) {
    // Given item name like "2 of #222001." or "3 of #222001; 5 of #222002."
    // Return array like (222001 => 2) or (222001 => 3, 222002 => 5)
    preg_match('/([0-9]?) of #([0-9]?)(.|;\s)/', $itemname, $matches);
    return $matches;
}

Calling the function with

print_r(parseItemName("3 of #222001; 5 of #222002."));

returns

Array ( [0] => 3 of #22 [1] => 3 [2] => 2 [3] => 2 )

Does anyone know how to make this work? I assume that preg_match() is not the best way to do this, but I'm not sure what else to try. I appreciate any ideas. Thank you!

Upvotes: 1

Views: 256

Answers (4)

lll
lll

Reputation: 12889

Aside from the adjustment to your regex pattern, you want to be using preg_match_all with the PREG_SET_ORDER flag set to make things simpler.

This will return a $matches array arranged like so:

array
  0 => 
    array
      0 => string '3 of #222001' (length=12)
      1 => string '3' (length=1)
      2 => string '222001' (length=6)
  1 => 
    array
      0 => string '5 of #222002' (length=12)
      1 => string '5' (length=1)
      2 => string '222002' (length=6)

The below example function now loops through all of the matches, and constructs a new array, using the second match as the key, and the first match as the value.

function parseItemName($itemname) {
    // Given item name like "2 of #222001." or "3 of #222001; 5 of #222002."
    // Return array like (222001 => 2) or (222001 => 3, 222002 => 5)
    preg_match_all('/(\d+)\sof\s#(\d+)/', $itemname, $matches, PREG_SET_ORDER);

    $newArray = array();

    foreach($matches as $match) {
        $newArray[$match[2]] = intval($match[1]);
    }

    return $newArray;
}

var_dump(parseItemName("3 of #222001; 5 of #222002."));

The output that is dumped will look like this:

array
  222001 => int 3
  222002 => int 5

Upvotes: 2

JMM
JMM

Reputation: 26827

function parseItemName( $itemname ) {

  preg_match_all( '/([0-9]+) of #([0-9]+)/', $itemname, $matches, PREG_SET_ORDER );

  $items = array();

  foreach ( $matches as $match ) {

    $items[ $match[2] ] = $match[1];

  }
  // foreach


  return $items;

}
// parseItemName

Upvotes: 0

Wouter J
Wouter J

Reputation: 41934

Use something like:

/(\d*?)\sof\s#(\d*)\b/

EDIT: Remove the lazy match as commented in this post.

Upvotes: 0

Marc B
Marc B

Reputation: 360792

([0-9]?)
      ^--- "0 or 1 of ...

What you want is + instead, which is "1 or more", and would capture all of the digits, not just the first one.

Upvotes: 1

Related Questions