Reputation: 937
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
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
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
Reputation: 41934
Use something like:
/(\d*?)\sof\s#(\d*)\b/
EDIT: Remove the lazy match as commented in this post.
Upvotes: 0
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