-2

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']));
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
Mark Alan
  • 15
  • 6

1 Answers1

0

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

mickmackusa
  • 43,625
  • 12
  • 83
  • 136