fork download
  1. <?php
  2. function parse($text)
  3. {
  4. // Find each character group: [...]
  5. preg_match_all('/(.*?)(?:\[([^[\]]{1,30})\]|$)/s', $text, $matches, PREG_SET_ORDER);
  6. $groups = [];
  7. foreach ($matches as $match) {
  8. if (!empty($match[1])) {
  9. // Prefix: foo
  10. $groups []= $match[1];
  11. }
  12. if (!empty($match[2])) {
  13. // Group: [a-z0-9]
  14. // For each range, add the chars to an array. ['a', 'b', ..., 'z', '0', ..., '9']
  15. $chrs = [];
  16. preg_match_all('/(.)(?:-(.))?/', $match[2], $ranges, PREG_SET_ORDER);
  17. foreach ($ranges as $rng)
  18. {
  19. if (empty($rng[2])) {
  20. $chrs []= $rng[1];
  21. }
  22. else {
  23. $chrs = array_merge($chrs, range($rng[1], $rng[2]));
  24. }
  25. }
  26. $groups []= $chrs;
  27. }
  28. }
  29. return $groups;
  30. }
  31.  
  32. function permute($groups, $index = 0)
  33. {
  34. $result = [];
  35. if ($index >= count($groups))
  36. {
  37. // Reached the end. Return a single, empty result.
  38. $result []= '';
  39. }
  40. else if (is_string($groups[$index]))
  41. {
  42. // Current group is a simple string. Prepend it to all tail results.
  43. $prefix = $groups[$index];
  44. foreach (permute($groups, $index+1) as $s)
  45. {
  46. $result []= $prefix . $s;
  47. }
  48. }
  49. else {
  50. // Otherwise it is an array of characters. Prepend each to every tail result.
  51. $chars = $groups[$index];
  52. foreach (permute($groups, $index+1) as $s)
  53. {
  54. foreach ($chars as $ch) {
  55. $result []= $ch . $s;
  56. }
  57. }
  58. }
  59.  
  60. return $result;
  61. }
  62.  
  63. $text = 'test[A-BXZ][0-1][x-z]foo';
  64.  
  65. $groups = parse($text);
  66. print_r($groups);
  67.  
  68. $permutations = permute($groups);
  69. print_r($permutations);
  70. ?>
Success #stdin #stdout 0.01s 20520KB
stdin
Standard input is empty
stdout
Array
(
    [0] => test
    [1] => Array
        (
            [0] => A
            [1] => B
            [2] => X
            [3] => Z
        )

    [2] => Array
        (
            [0] => 0
            [1] => 1
        )

    [3] => Array
        (
            [0] => x
            [1] => y
            [2] => z
        )

    [4] => foo
)
Array
(
    [0] => testA0xfoo
    [1] => testB0xfoo
    [2] => testX0xfoo
    [3] => testZ0xfoo
    [4] => testA1xfoo
    [5] => testB1xfoo
    [6] => testX1xfoo
    [7] => testZ1xfoo
    [8] => testA0yfoo
    [9] => testB0yfoo
    [10] => testX0yfoo
    [11] => testZ0yfoo
    [12] => testA1yfoo
    [13] => testB1yfoo
    [14] => testX1yfoo
    [15] => testZ1yfoo
    [16] => testA0zfoo
    [17] => testB0zfoo
    [18] => testX0zfoo
    [19] => testZ0zfoo
    [20] => testA1zfoo
    [21] => testB1zfoo
    [22] => testX1zfoo
    [23] => testZ1zfoo
)