1

i have a list of key=>value pairs from a JSON squirt. i sorted the array and i'm left with the following (excerpted relevant cases because they go as high as 92):

dir1summary
dir10summary
dir1summarydue
dir10summarydue
directive1
directive10
directivecode1
directivecode10

what i need to do is: 1) place all the digits at the end and 2) pad them to 2 digits (01,02,&c) so the list ends up looking like this:

directivesummary01
directivesummary10
directivesummarydue01
directivesummarydue10
directive01
directive10
directivecode01
directivecode10

i was hoping to do this with one REGEX statement given the obvious similarity in key names, but i got lost. here's what i have so far:

dir((\d{1,2}(summary|summarydue))|((ective\d{1,2})|(ectivecode\d{1,2})))

...aaaand i'm lost what to do next. how to move on? is there a better compact way to do this?

EDIT: this also means i have to replace 'dir' with 'directive'. it's implied in the result list, but i didnt' make a bullet item for it. also, the REGEX is all i was able to build at RegExer. thus the "lost what to do next" part.

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
WhiteRau
  • 818
  • 14
  • 32
  • Maybe https://regex101.com/r/OtWHmC/2/ with a `preg_replacecallback` to trim the leading `0` on +10 integers. Also in the future a shared `regex101` or `regexer` link would be much more useful. – user3783243 Mar 04 '20 at 05:44

1 Answers1

2
  • Match but don't capture dir
  • Match but don't capture the optional substring ective
  • Retain zero or more non-digital characters immediately after ective as capture group #1 (this accounts for optional substrings like summarydue)
  • Retain the whole integer as capture group #2
  • Retain the remainder of the string as capture group #3

  • In the custom function, hardcode directive, then append capture group #1 (which may be empty), then capture group #3 (might also be empty), finally left pad capture group #2 with a zero to a maximum length of 2-digits and append that value to the end of the string

Code: (Demo)

$strings = [
    'dir1summary',
    'dir10summary',
    'dir1summarydue',
    'dir10summarydue',
    'directive1',
    'directive10',
    'directivecode1',
    'directivecode10',
];

var_export(
    preg_replace_callback(
        '/dir(?:ective)?(\D*)(\d+)(.*)/',
        function ($m) {
            return "directive{$m[1]}{$m[3]}" . str_pad($m[2], 2, "0", STR_PAD_LEFT);
        },
        $strings
    )
);

Output:

array (
  0 => 'directivesummary01',
  1 => 'directivesummary10',
  2 => 'directivesummarydue01',
  3 => 'directivesummarydue10',
  4 => 'directive01',
  5 => 'directive10',
  6 => 'directivecode01',
  7 => 'directivecode10',
)

Alternatively, you could parse the string with sscanf(), then print the isolated components in the desired format with printf().

Code: (Demo)

foreach ($strings as $string) {
    sscanf($string, '%[^0-9]%d%s', $dir, $num, $str);
    printf("%s%s%02d\n", str_pad($dir, 9, 'ective'), $str, $num);
}
// same result strings as above
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
  • 1
    okay. this is not only solved, but explained so clearly and simply that i learned even more than i came here to! @mickmackusa, your obvious mastery of regex is clear. thank you for your time and effort. VERY much appreciated. wow... :D – WhiteRau Mar 04 '20 at 15:29
  • When you post a clear problem statement, a sufficiently large sample set, a desired output, and a coding attempt; you have a complete question that is very attractive to answer. I have no idea what a json squirt is, but that didn't matter because all of the logic was clearly expressed. I am very happy to generously share my knowledge on questions that add value to Stackoverflow. – mickmackusa Mar 04 '20 at 20:36
  • JSON squirt = a JSON array received via POST or GET. too much William Gibson as a youth. ;) – WhiteRau Mar 04 '20 at 21:45