Reputation: 3073
I found an error in some old code that hopefully I can fix pretty quickly, with the help of the SO community.
A user may insert multiple city/states into an array, so the array will look something like this:
Norfolk, VA, Chicago, IL, New York, NY
I need to retain the inner comma and using the trailing comma as the delimiter.
The current PHP code gets the data like this:
$deliveryCityArray = explode(',', $_POST['deliveryCity']);
When displayed in a grid, the City/State should be in the same column.
Unfortunately with my current code, the City will be in its own cell, and the State will be in the next row.
What do I need to add to retain the trailing comma but keep the inner comma?
Upvotes: 1
Views: 1607
Reputation: 76413
There is a pattern in the string you're trying to process: You want to explode
the input on each comma after 2 upper-case letters. In that case:
$array = preg_split('/(?<=, [A-Z]{2}),/', $str);
works just fine (DEMO)
(?<=
: Positive lookbehind assertion. The pattern will only match if it is preceded by a certain sub-pattern, [A-Z]{2})
: The sub-pattern: a comma, space and 2 upper-case chars (the closing bracket signals the end of the lookbehind assertion),
: a litteral ,
(which is matched if the lookbehind is successful). This character is matched and used to explode the string. The lookbehind is a zero-width match, so it's not treated as part of the delimiterIf the entire string is upper-case, the pattern needs to change a bit, but not a lot (Updated demo):
$array = preg_split('/(?<=,\s[A-Z]{2}\b),/', $upperStr);
I've simply added a \b
to the lookbehind (metacharacter that matches a word-boundary). That word boundary is optional anyway, seeing as we're matching , [A-Z]{2},
anyway.
Upvotes: 2
Reputation: 47992
When using regex, for best efficiency avoid using capture groups and lookarounds. This task can be accomplished without these techniques by leveraging \K
to "restart the fullstring match".
Code: (Demo)
$string='Norfolk, VA, Chicago, IL, New York, NY';
var_export(preg_split('/[A-Z]{2}\K, /',$string));
Output:
array (
0 => 'Norfolk, VA',
1 => 'Chicago, IL',
2 => 'New York, NY',
)
This pattern effectively says:
Upvotes: 0
Reputation: 1264
The only way you can do this is to make some assumptions - as long as you are confident that the 'separating' comma is always every other one, you could do something like this:
$results = array();
$tmp = explode(",",$_POST['deliveryCity']);
$idx = 0;
while ($idx < count($tmp)){
$results[] = $tmp[$idx] . "," . $tmp[$idx+1];
$idx += 2;
}
//$results will contain your resultant array.
Upvotes: 2
Reputation: 212452
Explode as normal, then chunk that resultant array into pairs, then walk the pairs and implode them again
$deliveryCity = 'Norfolk, VA, Chicago, IL, New York, NY';
$deliveryCityArray = array_map(
function($value) {
return implode(',', $value);
},
array_chunk(
explode(',', $deliveryCity),
2
)
);
Upvotes: 3