Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

rawilk's avatar
Level 47

PHP Regex Case Conversion

I'm trying to convert studly case/upper case words to snake case, and in most cases the Str::snake($string) helper would work fine, but with strings like FooID, it doesn't turn it into the string I want it to: it converts it to foo_i_d instead of foo_id.

I have a regular expression pattern that works in most cases, but there are few edge cases that I can't quite figure out.

The pattern I have is: /(?=[A-Z].)/

Here is what I'm needing the pattern to match with preg_split:

// Matches correctly
[
    'FooBar' => ['Foo', 'Bar'],
    'FooID' => ['Foo', 'ID'],
];

// Not correct
[
    'FooBARId' => ['Foo', 'B', 'A', 'R', 'Id'], // should be ['Foo', 'BAR', 'Id']
    'FooIDS' => ['Foo', 'I', 'DS'], // should be ['Foo', 'IDS']
];

Any help on this would be greatly appreciated.

0 likes
1 reply
rawilk's avatar
rawilk
OP
Best Answer
Level 47

Found the answer to my question. The pattern ended up being:

~[^A-Z]+\K|(?=[A-Z][^A-Z]+)~

Source: https://stackoverflow.com/questions/4519739/split-camelcase-word-into-words-with-php-preg-match-regular-expression/55681723#55681723

Solution:

protected function convert(string $string): string
{
    $pattern = '~[^A-Z]+\K|(?=[A-Z][^A-Z]+)~';

     return collect(preg_split($pattern, $string, -1, PREG_SPLIT_NO_EMPTY))
        ->map(fn (string $word) => strtolower($word))
        ->implode('_');
}
1 like

Please or to participate in this conversation.