JMP
JMP

Reputation: 1934

Split string to CamelCase words and also uppercase acronymns

Given a string containing CamelCase and also uppercase acronymns e.g. 'ManualABCTask';

How can it be split to a string with a space between all words and acronyms in a less wordy way?

I had the following process:

let initial = 'ManualABCTask'
//Split on single upper case followed by any number of lower case:
.split(/(['A-Z'][a-z]*)/g)
//the returned array includes empty string entries e.g. ["", "", "Manual", "A", "", "B", "", "C","", "Task", ""] so remove these:
.filter(x => x != '');

//When joining the array, the acronymn uppercase single letters have a space e.g. 'Manual A B C Task' so instead, reduce and add space only if array entry has more than one character
 let word = initial.reduce((prevVal,currVal) => {
    return  (currVal.length == 1) ? prevVal + currVal  : prevVal + ' ' + currVal + ' ';
}, '');

This does the job on the combinations it needs to e.g:

But it was a lot of code for the job done and surely could be handled in the initial regex.

I was experimenting while writing the question and with a tweak to the regex, got it down to one line, big improvement! So posting anyway with solution.

My regex know how isn't great so this could maybe be improved on still.

Upvotes: 2

Views: 582

Answers (3)

JvdV
JvdV

Reputation: 75870

I know near to nothing about JavaScript but i had a bash at it:

let initial = 'ManualABCTask'
initial = initial.replace(/([A-Z][a-z]+)/g, ' $1 ').trim();

Upvotes: 4

frost-nzcr4
frost-nzcr4

Reputation: 1620

There 2 groups: starting from head letter with following lowercases, and starting from head letter until next letter isn't lowercase:

find = new RegExp(
    "(" +
    "[A-Z][a-z]+" +  // Group starting from head letter with following lowercases
    "|" +
    "[A-Z]+(?![a-z])" +  // Group with head letters until next letter isn't lowercase:
    ")",
    "g"
)
initial = 'ManualABCTask'.split(find)

Upvotes: 1

JMP
JMP

Reputation: 1934

As mentioned in post, changed to handle in regex:

  initial = 'ManualABCTask'.split(/(['A-Z']{2,99})(['A-Z'][a-z]*)/g).join(' ');

Group any concurrent upper characters with length of 2 to 99 to get the acronyms, and any single upper character followed by any number of lower to get the other words. Join with space.

Upvotes: 0

Related Questions