If user adds a name and they want to create multiple fields, they can put numeric values in a ranged format. If they type in A1-7
, it will create 7 names A1 A2 A3 A4 A5 A6 A7
. Deepening on the range, it creates the title according to provided range the user can use a comma to separate multiple ranges. Use a number range with a dash in-between to create multiple units in a row. Letters can be used before or after the first number in each range.
Example: A1-3, 5B-7
will create 6 units (A1, A2, A3, 5B, 6B, 7B
)
I tried using the explode function to first separate it by comma, but I am stuck on how to expand the ranges.
$units = array_map('trim', explode(',', $_POST['title']));
You only need to adapt Populate array of integers from a comma-separated string of numbers and hyphenated number ranges to accommodate your two range signatures. preg_replace_callback_array()
is a tidy way to implement the two replacement rules. If you need to convert the hydrated/expanded string into an array, then just explode on the comma-space delimiters.
Code: (Demo)
$string = 'A1-3, 5B-7';
echo preg_replace_callback_array(
[
'/(\d+)([A-Z]+)-(\d+)/' => fn($m) => implode($m[2] . ', ', range($m[1], $m[3])) . $m[2],
'/([A-Z]+)(\d+)-(\d+)/' => fn($m) => $m[1] . implode(', ' . $m[1], range($m[2], $m[3])),
],
$string
);
// A1, A2, A3, 5B, 6B, 7B
A more verbose way without a preg_ function call is to attempt parsing the values and expanding the ranges with a nested loop. (Demo)
$string = 'A1-3, A14, 5B-7';
$result = [];
foreach (explode(', ', $string) as $value) {
if (sscanf($value, '%[A-Z]%d-%d', $letter, $low, $high) === 3) {
for ($x = $low; $x <= $high; ++$x) {
$result[] = $letter . $x;
}
} elseif (sscanf($value, '%d%[A-Z]-%d', $low, $letter, $high) === 3) {
for ($x = $low; $x <= $high; ++$x) {
$result[] = $x . $letter;
}
} else {
$result[] = $value;
}
}
var_export($result);
Output:
array (
0 => 'A1',
1 => 'A2',
2 => 'A3',
3 => 'A14',
4 => '5B',
5 => '6B',
6 => '7B',
)
...there will be many ways to perform this task