Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Formatting camel case to readable in PHP while skipping abbreviations

So i am stuck - I have looked at tons of answers in here, but none seems to resolve my last problem.

Through an API with JSON, I receive an equipment list in a camelcase format. I can not change that.

I need this camelcase to be translated into normal language -

So far i have gotten most words seperated through:

$string = "SomeEquipmentHere";

$spaced = preg_replace('/([A-Z])/', ' $1', $string);
var_dump($spaced);

string ' Some Equipment Here' (length=20)

$trimmed = trim($spaced);
var_dump($trimmed);
string 'Some Equipment Here' (length=19)

Which is working fine - But in some of the equipments consists of abbreviations

"ABSBrakes" - this would require ABS and separated from Brakes

I can't check for several uppercases next to each other since it will then keep ABS and Brakes together - there are more like these, ie: "CDRadio"

So what is want is the output to be:

"ABS Brakes"

Is there a way to format it so, if there is uppercases next to eachother, then only add a space before the last uppercase letter of that sequence?

I am not strong in regex.

EDIT

Both contributions are awesome - people coming here later should read both answers

The last problems to consists are the following patterns :

"ServiceOK" becomes "Service O K"

"ESP" becomes "ES P"

The pattern only consisting of a pure uppercased abbreviation is fixed by a function counting lowercase letter, if there is none, it will skip over the preg_replace().

But as Flying wrote in the comments on his answer, there could potentially be a lot of instances not covered by his regex, and an answer could be impossible - I don't know if this could be a challenge for the regex.

Possibly by adding some "If there is not a lowercase after the uppercase, there should not be inserted a space" rule

like image 676
Stender Avatar asked Nov 22 '17 09:11

Stender


1 Answers

Here is how it can be solved:

$tests = [
    'SomeEquipmentHere',
    'ABSBrakes',
    'CDRadio',
    'Valve14',
];
foreach ($tests as $test) {
    echo trim(preg_replace('/\s+/', ' ', preg_replace('/([A-Z][a-z]+)|([A-Z]+(?=[A-Z]))|(\d+)/', '$1 $2 $3', $test)));
    echo "\n";
}

Related test on regex101.

UPDATE: Added example for additional question

like image 131
Flying Avatar answered Sep 19 '22 17:09

Flying