265

How can I convert a string either like 'helloThere' or 'HelloThere' to 'Hello There' in JavaScript?

worc
  • 3,654
  • 3
  • 31
  • 35
HyderA
  • 20,651
  • 42
  • 112
  • 180

27 Answers27

353

const text = 'helloThereMister';
const result = text.replace(/([A-Z])/g, " $1");
const finalResult = result.charAt(0).toUpperCase() + result.slice(1);
console.log(finalResult);

capitalize the first letter - as an example. Note the space in " $1".


Here's a typescript function that does it as well:

function camelCaseToWords(s: string) {
  const result = s.replace(/([A-Z])/g, ' $1');
  return result.charAt(0).toUpperCase() + result.slice(1);
}

Of course, in case the first letter is already capital - you would have a spare space to remove.

ICW
  • 4,875
  • 5
  • 27
  • 33
ZenMaster
  • 12,363
  • 5
  • 36
  • 59
  • 1
    I dig the use of spaces in `text.replace`, I've been padding function calls with 2+ arguments with spaces for readability too – rkd Jan 08 '17 at 20:44
  • 8
    uSBPorts=>U S B Ports, not what I expect, I want a USB Ports – signonsridhar Jun 19 '17 at 18:27
  • what about writing like `Non-GoogleChrome`? – tim Sep 09 '19 at 06:07
  • 15
    @signonsridhar Man, if somebody wrote the lowercase `usb ports` as `uSBPorts`, I'd steal the shift keys out of their keyboard. I'd hope it'd be `usbPorts`. In cases such as `theUSA`, you could have an option, such as `consecutiveCapsMode`, with different modes: `lower` and `split`, for instance. Then do `camelToSentence('theUSA', { consecutiveCapsMode: 'lower' })` should return `theUsa`, etc. – Nick Bull Aug 12 '20 at 17:19
  • Further to above, that'd be something like: `camelToKebab = (str, mode) { let rgx = /defaultRgx/; switch(mode) { 'lower': rgx = /lowerRgx/; break; } ... }` – Nick Bull Aug 12 '20 at 17:25
  • I just wanted to mention that this code adds an extra space at the beginning of each `text` – Vlad Topala Dec 15 '20 at 15:21
  • @VladTopala Only if the first letter is capital. And it's mentioned in the answer. – ZenMaster Dec 16 '20 at 09:52
  • I wanted to convert strings that started with an uppercase character, so I modified it a little to only consider uppercase characters after a lowercase character, eg: LeftVM would become "Left VM" `const result = key.replace( /([a-z])([A-Z])/g, "$1 $2" );` – Chaitanya Bankanhal Mar 09 '21 at 11:48
  • To modify this to handle camelCase strings with numbers, use this pattern instead: `/([A-Z]|([0-9]+))/g` – willpwa Jan 24 '22 at 16:16
  • if using this text in HTML, you can apply text-transform: capitalize css rule to capitalize all words. – Sharas Aug 07 '22 at 12:33
  • @Sharas Regardless of the CSS capitalization actually being able to do what is required, I would argue that this a bad practice, as capitalization here is more likely to not for cosmetic purposes only and carries a semantic significance. Thus doing capitalization in CSS you mix your concerns and insert what is, essentially, a business logic into your CSS. – ZenMaster Aug 09 '22 at 14:58
  • this gives breaking result for all cap non underscored string – Tukaram Bhosale Aug 17 '22 at 09:14
193

Alternatively using lodash:

lodash.startCase(str);

Example:

_.startCase('helloThere');
// ➜ 'Hello There'

Lodash is a fine library to give shortcut to many everyday js tasks.There are many other similar string manipulation functions such as camelCase, kebabCase etc.

Wtower
  • 18,848
  • 11
  • 103
  • 80
67

I had a similar problem and dealt with it like this:

stringValue.replace(/([A-Z]+)*([A-Z][a-z])/g, "$1 $2")

For a more robust solution:

stringValue.replace(/([A-Z]+)/g, " $1").replace(/([A-Z][a-z])/g, " $1")

http://jsfiddle.net/PeYYQ/

Input:

 helloThere 
 HelloThere 
 ILoveTheUSA
 iLoveTheUSA

Output:

 hello There 
 Hello There 
 I Love The USA
 i Love The USA
James Khoury
  • 21,330
  • 4
  • 34
  • 65
54

Example without side effects.

function camel2title(camelCase) {
  // no side-effects
  return camelCase
    // inject space before the upper case letters
    .replace(/([A-Z])/g, function(match) {
       return " " + match;
    })
    // replace first char with upper case
    .replace(/^./, function(match) {
      return match.toUpperCase();
    });
}

In ES6

const camel2title = (camelCase) => camelCase
  .replace(/([A-Z])/g, (match) => ` ${match}`)
  .replace(/^./, (match) => match.toUpperCase())
  .trim();
Community
  • 1
  • 1
renevanderark
  • 975
  • 7
  • 15
41

The best string I've found for testing camel-case-to-title-case functions is this ridiculously nonsensical example, which tests a lot of edge cases. To the best of my knowledge, none of the previously posted functions handle this correctly:

__ToGetYourGEDInTimeASongAboutThe26ABCsIsOfTheEssenceButAPersonalIDCardForUser_456InRoom26AContainingABC26TimesIsNotAsEasyAs123ForC3POOrR2D2Or2R2D

This should be converted to:

To Get Your GED In Time A Song About The 26 ABCs Is Of The Essence But A Personal ID Card For User 456 In Room 26A Containing ABC 26 Times Is Not As Easy As 123 For C3PO Or R2D2 Or 2R2D

If you want just a simple function that handles cases like the one above (and more cases than many of the previously answers), here's the one I wrote. This code isn't particularly elegant or fast, but it's simple, understandable, and works.

The snippet below contains an online runnable example:

var mystrings = [ "__ToGetYourGEDInTimeASongAboutThe26ABCsIsOfTheEssenceButAPersonalIDCardForUser_456InRoom26AContainingABC26TimesIsNotAsEasyAs123ForC3POOrR2D2Or2R2D", "helloThere", "HelloThere", "ILoveTheUSA", "iLoveTheUSA", "DBHostCountry", "SetSlot123ToInput456", "ILoveTheUSANetworkInTheUSA", "Limit_IOC_Duration", "_This_is_a_Test_of_Network123_in_12__days_",  "ASongAboutTheABCsIsFunToSing", "CFDs", "DBSettings", "IWouldLove1Apple", "Employee22IsCool", "SubIDIn",  "ConfigureABCsImmediately", "UseMainNameOnBehalfOfSubNameInOrders" ];

// Take a single camel case string and convert it to a string of separate words (with spaces) at the camel-case boundaries.
// 
// E.g.:
//    __ToGetYourGEDInTimeASongAboutThe26ABCsIsOfTheEssenceButAPersonalIDCardForUser_456InRoom26AContainingABC26TimesIsNotAsEasyAs123ForC3POOrR2D2Or2R2D
//                                            --> To Get Your GED In Time A Song About The 26 ABCs Is Of The Essence But A Personal ID Card For User 456 In Room 26A Containing ABC 26 Times Is Not As Easy As 123 For C3PO Or R2D2 Or 2R2D
//    helloThere                              --> Hello There
//    HelloThere                              --> Hello There 
//    ILoveTheUSA                             --> I Love The USA
//    iLoveTheUSA                             --> I Love The USA
//    DBHostCountry                           --> DB Host Country
//    SetSlot123ToInput456                    --> Set Slot 123 To Input 456
//    ILoveTheUSANetworkInTheUSA              --> I Love The USA Network In The USA
//    Limit_IOC_Duration                      --> Limit IOC Duration
//    This_is_a_Test_of_Network123_in_12_days --> This Is A Test Of Network 123 In 12 Days
//    ASongAboutTheABCsIsFunToSing            --> A Song About The ABCs Is Fun To Sing
//    CFDs                                    --> CFDs
//    DBSettings                              --> DB Settings
//    IWouldLove1Apple                        --> I Would Love 1 Apple
//    Employee22IsCool                        --> Employee 22 Is Cool
//    SubIDIn                                 --> Sub ID In
//    ConfigureCFDsImmediately                --> Configure CFDs Immediately
//    UseTakerLoginForOnBehalfOfSubIDInOrders --> Use Taker Login For On Behalf Of Sub ID In Orders
//
function camelCaseToTitleCase(in_camelCaseString) {
        var result = in_camelCaseString                         // "__ToGetYourGEDInTimeASongAboutThe26ABCsIsOfTheEssenceButAPersonalIDCardForUser_456InRoom26AContainingABC26TimesIsNotAsEasyAs123ForC3POOrR2D2Or2R2D"
            .replace(/(_)+/g, ' ')                              // " ToGetYourGEDInTimeASongAboutThe26ABCsIsOfTheEssenceButAPersonalIDCardForUser 456InRoom26AContainingABC26TimesIsNotAsEasyAs123ForC3POOrR2D2Or2R2D"
            .replace(/([a-z])([A-Z][a-z])/g, "$1 $2")           // " To Get YourGEDIn TimeASong About The26ABCs IsOf The Essence ButAPersonalIDCard For User456In Room26AContainingABC26Times IsNot AsEasy As123ForC3POOrR2D2Or2R2D"
            .replace(/([A-Z][a-z])([A-Z])/g, "$1 $2")           // " To Get YourGEDIn TimeASong About The26ABCs Is Of The Essence ButAPersonalIDCard For User456In Room26AContainingABC26Times Is Not As Easy As123ForC3POOr R2D2Or2R2D"
            .replace(/([a-z])([A-Z]+[a-z])/g, "$1 $2")          // " To Get Your GEDIn Time ASong About The26ABCs Is Of The Essence But APersonal IDCard For User456In Room26AContainingABC26Times Is Not As Easy As123ForC3POOr R2D2Or2R2D"
            .replace(/([A-Z]+)([A-Z][a-z][a-z])/g, "$1 $2")     // " To Get Your GEDIn Time A Song About The26ABCs Is Of The Essence But A Personal ID Card For User456In Room26A ContainingABC26Times Is Not As Easy As123ForC3POOr R2D2Or2R2D"
            .replace(/([a-z]+)([A-Z0-9]+)/g, "$1 $2")           // " To Get Your GEDIn Time A Song About The 26ABCs Is Of The Essence But A Personal ID Card For User 456In Room 26A Containing ABC26Times Is Not As Easy As 123For C3POOr R2D2Or 2R2D"
            
            // Note: the next regex includes a special case to exclude plurals of acronyms, e.g. "ABCs"
            .replace(/([A-Z]+)([A-Z][a-rt-z][a-z]*)/g, "$1 $2") // " To Get Your GED In Time A Song About The 26ABCs Is Of The Essence But A Personal ID Card For User 456In Room 26A Containing ABC26Times Is Not As Easy As 123For C3PO Or R2D2Or 2R2D"
            .replace(/([0-9])([A-Z][a-z]+)/g, "$1 $2")          // " To Get Your GED In Time A Song About The 26ABCs Is Of The Essence But A Personal ID Card For User 456In Room 26A Containing ABC 26Times Is Not As Easy As 123For C3PO Or R2D2Or 2R2D"  

            // Note: the next two regexes use {2,} instead of + to add space on phrases like Room26A and 26ABCs but not on phrases like R2D2 and C3PO"
            .replace(/([A-Z]{2,})([0-9]{2,})/g, "$1 $2")        // " To Get Your GED In Time A Song About The 26ABCs Is Of The Essence But A Personal ID Card For User 456 In Room 26A Containing ABC 26 Times Is Not As Easy As 123 For C3PO Or R2D2 Or 2R2D"
            .replace(/([0-9]{2,})([A-Z]{2,})/g, "$1 $2")        // " To Get Your GED In Time A Song About The 26 ABCs Is Of The Essence But A Personal ID Card For User 456 In Room 26A Containing ABC 26 Times Is Not As Easy As 123 For C3PO Or R2D2 Or 2R2D"
            .trim()                                             // "To Get Your GED In Time A Song About The 26 ABCs Is Of The Essence But A Personal ID Card For User 456 In Room 26A Containing ABC 26 Times Is Not As Easy As 123 For C3PO Or R2D2 Or 2R2D"
           ;

  // capitalize the first letter
  return result.charAt(0).toUpperCase() + result.slice(1);
}

for (var i = 0; i < mystrings.length; i++) {
  jQuery(document.body).append("<br />\"");
  jQuery(document.body).append(camelCaseToTitleCase(mystrings[i]));
  jQuery(document.body).append("\"<br>(was: \"");
  jQuery(document.body).append(mystrings[i]);
  jQuery(document.body).append("\") <br />");
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.2.3/jquery.min.js"></script>
Chris Kline
  • 2,249
  • 26
  • 32
  • 1
    The undercore spaced test cases do not work anymore, just a heads up. Adding: ```.replace(/_/g,' ')``` solves this. Also, adding ```.replace(\&\, ' & ')``` supports ampersand splitting – Justin Dalrymple Oct 02 '20 at 22:29
  • 1
    Thanks for pointing that out @JustinDalrymple. Our internal code wraps the ```camelCaseToTitleCase()``` function above in a helper that handles the underscores, so I didn't notice the omission when I posted it. I'll fix the code above now. – Chris Kline Oct 07 '20 at 12:48
  • 1
    This is the most complete solution I found so far. Thank you! – janhink Feb 10 '21 at 12:14
18

Based on one of the examples above I came up with this:

const camelToTitle = (camelCase) => camelCase
  .replace(/([A-Z])/g, (match) => ` ${match}`)
  .replace(/^./, (match) => match.toUpperCase())
  .trim()

It works for me because it uses .trim() to handle the edge case where the first letter is capitalized and you end up with a extra leading space.

Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim

Anthony S.
  • 181
  • 1
  • 3
12

Ok, I'm a few years late to the game, but I had a similar question, and I wanted to make a one-replace solution for every possible input. I must give most of the credit to @ZenMaster in this thread and @Benjamin Udink ten Cate in this thread. Here's the code:

var camelEdges = /([A-Z](?=[A-Z][a-z])|[^A-Z](?=[A-Z])|[a-zA-Z](?=[^a-zA-Z]))/g;
var textArray = ["lowercase",
                 "Class",
                 "MyClass",
                 "HTML",
                 "PDFLoader",
                 "AString",
                 "SimpleXMLParser",
                 "GL11Version",
                 "99Bottles",
                 "May5",
                 "BFG9000"];
var text;
var resultArray = [];
for (var i = 0; i < textArray.length; i++){
    text = textArray[i];
    text = text.replace(camelEdges,'$1 ');
    text = text.charAt(0).toUpperCase() + text.slice(1);
    resultArray.push(text);
}

It has three clauses, all using lookahead to prevent the regex engine from consuming too many characters:

  1. [A-Z](?=[A-Z][a-z]) looks for a capital letter that is followed by a capital then a lowercase. This is to end acronyms like USA.
  2. [^A-Z](?=[A-Z]) looks for a non-capital-letter followed by a capital letter. This ends words like myWord and symbols like 99Bottles.
  3. [a-zA-Z](?=[^a-zA-Z]) looks for a letter followed by a non-letter. This ends words before symbols like BFG9000.

This question was at the top of my search results, so hopefully I can save others some time!

krishna217
  • 13
  • 5
Chris
  • 121
  • 1
  • 2
9

Here's my version of it. It adds a space before every UpperCase english letter that comes after a lowercase english letter and also capitalizes the first letter if needed:

For example:
thisIsCamelCase --> This Is Camel Case
this IsCamelCase --> This Is Camel Case
thisIsCamelCase123 --> This Is Camel Case123

  function camelCaseToTitleCase(camelCase){
    if (camelCase == null || camelCase == "") {
      return camelCase;
    }

    camelCase = camelCase.trim();
    var newText = "";
    for (var i = 0; i < camelCase.length; i++) {
      if (/[A-Z]/.test(camelCase[i])
          && i != 0
          && /[a-z]/.test(camelCase[i-1])) {
        newText += " ";
      }
      if (i == 0 && /[a-z]/.test(camelCase[i]))
      {
        newText += camelCase[i].toUpperCase();
      } else {
        newText += camelCase[i];
      }
    }

    return newText;
  }
asafd
  • 315
  • 4
  • 14
8

This implementation takes consecutive uppercase letters and numbers in consideration.

function camelToTitleCase(str) {
  return str
    .replace(/[0-9]{2,}/g, match => ` ${match} `)
    .replace(/[^A-Z0-9][A-Z]/g, match => `${match[0]} ${match[1]}`)
    .replace(/[A-Z][A-Z][^A-Z0-9]/g, match => `${match[0]} ${match[1]}${match[2]}`)
    .replace(/[ ]{2,}/g, match => ' ')
    .replace(/\s./g, match => match.toUpperCase())
    .replace(/^./, match => match.toUpperCase())
    .trim();
}

// ----------------------------------------------------- //

var testSet = [
    'camelCase',
    'camelTOPCase',
    'aP2PConnection',
    'superSimpleExample',
    'aGoodIPAddress',
    'goodNumber90text',
    'bad132Number90text',
];

testSet.forEach(function(item) {
    console.log(item, '->', camelToTitleCase(item));
});

Expected output:

camelCase -> Camel Case
camelTOPCase -> Camel TOP Case
aP2PConnection -> A P2P Connection
superSimpleExample -> Super Simple Example
aGoodIPAddress -> A Good IP Address
goodNumber90text -> Good Number 90 Text
bad132Number90text -> Bad 132 Number 90 Text
Dipu
  • 6,999
  • 4
  • 31
  • 48
  • I'd use Chris Kline's answer which accomodates for strings like "IP Address" (where this function turns it into "I P Address" – John Hamm Jan 24 '20 at 21:44
  • 1
    @JohnHamm Your input is "IP Address", right? It is not a camel case! Read about what camel case is here: https://en.wikipedia.org/wiki/Camel_case Do not put space between and input "IPAddress" only. This function works fine. – Dipu Jan 25 '20 at 12:26
5

One more solution based on RegEx.

respace(str) {
  const regex = /([A-Z])(?=[A-Z][a-z])|([a-z])(?=[A-Z])/g;
  return str.replace(regex, '$& ');
}

Explanation

The above RegEx consist of two similar parts separated by OR operator. The first half:

  1. ([A-Z]) - matches uppercase letters...
  2. (?=[A-Z][a-z]) - followed by a sequence of uppercase and lowercase letters.

When applied to sequence FOo, this effectively matches its F letter.

Or the second scenario:

  1. ([a-z]) - matches lowercase letters...
  2. (?=[A-Z]) - followed by an uppercase letter.

When applied to sequence barFoo, this effectively matches its r letter.

When all replace candidates were found, the last thing to do is to replace them with the same letter but with an additional space character. For this we can use '$& ' as a replacement, and it will resolve to a matched substring followed by a space character.

Example

const regex = /([A-Z])(?=[A-Z][a-z])|([a-z])(?=[A-Z])/g
const testWords = ['ACoolExample', 'fooBar', 'INAndOUT', 'QWERTY', 'fooBBar']

testWords.map(w => w.replace(regex, '$& '))
->(5) ["A Cool Example", "foo Bar", "IN And OUT", "QWERTY", "foo B Bar"]
itachi
  • 3,389
  • 2
  • 24
  • 29
5

If you deal with Capital Camel Case this snippet can help you, also it contains some specs so you could be sure that it matches appropriate to your case.

export const fromCamelCaseToSentence = (word) =>
  word
    .replace(/([A-Z][a-z]+)/g, ' $1')
    .replace(/([A-Z]{2,})/g, ' $1')
    .replace(/\s{2,}/g, ' ')
    .trim();

And specs:

describe('fromCamelCaseToSentence', () => {
 test('does not fall with a single word', () => {
   expect(fromCamelCaseToSentence('Approved')).toContain('Approved')
   expect(fromCamelCaseToSentence('MDA')).toContain('MDA')
 })

 test('does not fall with an empty string', () => {
   expect(fromCamelCaseToSentence('')).toContain('')
 })

 test('returns the separated by space words', () => {
   expect(fromCamelCaseToSentence('NotApprovedStatus')).toContain('Not Approved Status')
   expect(fromCamelCaseToSentence('GDBState')).toContain('GDB State')
   expect(fromCamelCaseToSentence('StatusDGG')).toContain('Status DGG')
 })
})
Purkhalo Alex
  • 3,309
  • 29
  • 27
5

Using JS's String.prototype.replace() and String.prototype.toUpperCase()

const str = "thisIsATestString";
const res = str.replace(/^[a-z]|[A-Z]/g, (c, i) => (i? " " : "") + c.toUpperCase());

console.log(res);  // "This Is A Test String"
Roko C. Buljan
  • 196,159
  • 39
  • 305
  • 313
5

My split case solution which behaves the way I want:

const splitCase = s => !s || s.indexOf(' ') >= 0 ? s :
    (s.charAt(0).toUpperCase() + s.substring(1))
        .split(/(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])/g)
        .map(x => x.replace(/([0-9]+)/g,'$1 '))
        .join(' ')

Input

'a,abc,TheId,TheID,TheIDWord,TheID2Word,Leave me Alone!'
.split(',').map(splitCase)
.forEach(x => console.log(x))

Output

A
Abc
The Id
The ID
The ID Word
The ID2 Word
Leave me Alone!

As this above function requires Lookbehind in JS which isn't currently implemented in Safari, I've rewritten the implementation to not use RegEx below:

const isUpper = c => c >= 'A' && c <= 'Z'
const isDigit = c => c >= '0' && c <= '9'
const upperOrDigit = c => isUpper(c) || isDigit(c)

function splitCase(s) {
    let to = []
    if (typeof s != 'string') return to
    let lastSplit = 0
    for (let i=0; i<s.length; i++) {
        let c = s[i]
        let prev = i>0 ? s[i-1] : null
        let next = i+1 < s.length ? s[i+1] : null
        if (upperOrDigit(c) && (!upperOrDigit(prev) || !upperOrDigit(next))) {
            to.push(s.substring(lastSplit, i))
            lastSplit = i
        }
    }
    to.push(s.substring(lastSplit, s.length))
    return to.filter(x => !!x)
}
mythz
  • 141,670
  • 29
  • 246
  • 390
  • This is slick, but it's worth noting that if you need to support Safari, the regex uses lookbehind, [which is not supported in Safari yet](https://caniuse.com/js-regexp-lookbehind). – aeggum May 24 '22 at 13:53
  • @aeggum yeah I found out about the issue in Safari later, I've updated my answer with the non-RegEx solution I've ended up using. – mythz May 24 '22 at 14:02
5

You can use a function like this:

function fixStr(str) {
    var out = str.replace(/^\s*/, "");  // strip leading spaces
    out = out.replace(/^[a-z]|[^\s][A-Z]/g, function(str, offset) {
        if (offset == 0) {
            return(str.toUpperCase());
        } else {
            return(str.substr(0,1) + " " + str.substr(1).toUpperCase());
        }
    });
    return(out);
}

"hello World" ==> "Hello World"
"HelloWorld" ==> "Hello World"
"FunInTheSun" ==? "Fun In The Sun"

Code with a bunch of test strings here: http://jsfiddle.net/jfriend00/FWLuV/.

Alternate version that keeps leading spaces here: http://jsfiddle.net/jfriend00/Uy2ac/.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • I know it wasn't a requirement in the question, but your solution doesn't work for `" helloWorld"`, for example. – ZenMaster Aug 29 '11 at 02:32
  • Yep, that's a new requirement. I tried to do exactly what you originally asked for. Anyway, the short cut way is easy to stip off leading spaces if you don't need them there anyway. If you wanted them left in place, that could be done also. – jfriend00 Aug 29 '11 at 02:50
  • Here's a jsFiddle that shows a method that works with the new require of " helloWorld" and keeps the leading space (if you want that): http://jsfiddle.net/jfriend00/Uy2ac/. – jfriend00 Aug 29 '11 at 03:11
  • Nice. I wonder about the performance of it, though. The handler function will be called on every match, won't it? – ZenMaster Aug 29 '11 at 03:17
  • If you're doing a zillion of these in a performance-sensitive setting, it would take a some jsperf testing in a bunch of browsers to see what the fastest solution would be. Calling a callback is no big deal. Regular expressions, of any kind, are rarely the fastest solution vs. special purpose code, but they save a lot of code (and often some bugs) so are often the desired choice. It depends upon your requirements. – jfriend00 Aug 29 '11 at 03:32
4

try this library

http://sugarjs.com/api/String/titleize

'man from the boondocks'.titleize()>"Man from the Boondocks"
'x-men: the last stand'.titleize()>"X Men: The Last Stand"
'TheManWithoutAPast'.titleize()>"The Man Without a Past"
'raiders_of_the_lost_ark'.titleize()>"Raiders of the Lost Ark"
Barno
  • 3,271
  • 5
  • 28
  • 58
4

The most compatible answer for consecutive capital-case words is this:

const text = 'theKD';
const result = text.replace(/([A-Z]{1,})/g, " $1");
const finalResult = result.charAt(0).toUpperCase() + result.slice(1);
console.log(finalResult);
  • It's also compatible with The KD and it will not convert it to The K D.
double-beep
  • 5,031
  • 17
  • 33
  • 41
Colduction
  • 103
  • 7
2

None of the answers above worked perfectly for me, so had to come with own bicycle:

function camelCaseToTitle(camelCase) {
    if (!camelCase) {
        return '';
    }

    var pascalCase = camelCase.charAt(0).toUpperCase() + camelCase.substr(1);
    return pascalCase
        .replace(/([a-z])([A-Z])/g, '$1 $2')
        .replace(/([A-Z])([A-Z][a-z])/g, '$1 $2')
        .replace(/([a-z])([0-9])/gi, '$1 $2')
        .replace(/([0-9])([a-z])/gi, '$1 $2');
}

Test cases:

null => ''
'' => ''
'simpleString' => 'Simple String'
'stringWithABBREVIATIONInside => 'String With ABBREVIATION Inside'
'stringWithNumber123' => 'String With Number 123'
'complexExampleWith123ABBR890Etc' => 'Complex Example With 123 ABBR 890 Etc'
Vitaliy Ulantikov
  • 10,157
  • 3
  • 61
  • 54
2

This works for me check this out

CamelcaseToWord("MyName"); // returns My Name

    function CamelcaseToWord(string){
      return string.replace(/([A-Z]+)/g, " $1").replace(/([A-Z][a-z])/g, " $1");
    }
Poorna Rao
  • 335
  • 4
  • 20
2

I didn't try everyone's answer, but the few solutions I tinkered with did not match all of my requirements.

I was able to come up with something that did...

export const jsObjToCSSString = (o={}) =>
    Object.keys(o)
          .map(key => ({ key, value: o[key] }))
          .map(({key, value}) =>
              ({
                key: key.replace( /([A-Z])/g, "-$1").toLowerCase(),
                value
              })
          )
          .reduce(
              (css, {key, value}) => 
                  `${css} ${key}: ${value}; `.trim(), 
              '')
Tabbyofjudah
  • 1,973
  • 3
  • 17
  • 29
2

I think this can be done just with the reg exp /([a-z]|[A-Z]+)([A-Z])/g and replacement "$1 $2".

ILoveTheUSADope -> I Love The USA Dope

2
HTTPRequest_ToServer-AndWaiting --> HTTP Request To Server And Waiting

function toSpaceCase(str) {
  return str
    .replace(/[-_]/g, ' ')
    // insert a space between lower & upper: HttpRequest => Http Request
    .replace(/([a-z])([A-Z])/g, '$1 $2')
    // space before last upper in a sequence followed by lower: XMLHttp => XML Http
    .replace(/\b([A-Z]+)([A-Z])([a-z])/, '$1 $2$3')
    // add space between numbers and letters: Col1 => Col 1
    .replace(/([a-zA-Z])([0-9])/g, '$1 $2').replace(/([0-9])([a-zA-Z])/g, '$1 $2')
    // uppercase the first character
    .replace(/^./, firstChar => firstChar.toUpperCase())
    // replace multiple whitespaces with one
    .replace(/\s+/g, ' ')
    .trim();
}
console.log('HTTPRequest_ToServer-AndWaiting','->', toSpaceCase('HTTPRequest_ToServer-AndWaiting'))
console.log('simple','->', toSpaceCase('simple'))
console.log('testCol1','->', toSpaceCase('testCol1'))
Tim Kozak
  • 4,026
  • 39
  • 44
Jason Song
  • 2,224
  • 1
  • 10
  • 7
1

Below is link which demonstrates camel case string to sentence string using regex.

Input

myCamelCaseSTRINGToSPLITDemo

Output

my Camel Case STRING To SPLIT Demo


This is regex for conversion of camel case to sentence text

(?=[A-Z][a-z])|([A-Z]+)([A-Z][a-rt-z][a-z]\*)

with $1 $2 as subsitution.

Click to view the conversion on regex

Kos
  • 4,890
  • 9
  • 38
  • 42
Rahul
  • 74
  • 8
1

Input javaScript

Output Java Script

   var text = 'javaScript';
    text.replace(/([a-z])([A-Z][a-z])/g, "$1 $2").charAt(0).toUpperCase()+text.slice(1).replace(/([a-z])([A-Z][a-z])/g, "$1 $2");
Manas Sahu
  • 779
  • 8
  • 8
0

Undercover C programmer. If like me you want to preserve acronyms and don't want to look at cryptic patterns, then perhaps you may like this:

function isUpperCase (str) {
  return str === str.toUpperCase()
}

export function camelCaseToTitle (str) {
  for (let i = str.length - 1; i > 0; i--) {
    if (!isUpperCase(str[i - 1]) && isUpperCase(str[i])) {
      str = str.slice(0, i) + ' ' + str.slice(i)
    }
  }
  return str.charAt(0).toUpperCase() + str.slice(1)
}
PJRobot
  • 1,306
  • 13
  • 14
0

This solution works also for other Unicode characters which are not in the [A-Z] range. E.g. Ä, Ö, Å.

let camelCaseToTitleCase = (s) => (
  s.split("").reduce(
    (acc, letter, i) => (
      i === 0 || console.log(acc, letter, i)
        ? [...acc, letter.toUpperCase()] 
        : letter === letter.toUpperCase()
        ? [...acc, " ", letter]
        : [...acc, letter] 
    ), []
  ).join("")
)

const myString = "ArchipelagoOfÅland"
camelCaseToTitleCase(myString)
fcole90
  • 71
  • 2
  • 9
0
.replace(/([a-z])([A-Z])/g, '$1 $2')
.replace(/([A-Z]+)([A-Z][a-z]+)/g, '$1 $2')
.replace(/^./, m => m.toUpperCase())

First RE: replaces ‘xyzABCDef’ with ‘xyz ABCDef’

Second RE: replaces ‘xyz ABCDef’ with ‘xyz ABC Def’

Third one: uppercases first letter

Moritz Ringler
  • 9,772
  • 9
  • 21
  • 34
Billy
  • 341
  • 3
  • 11
-1

Adding yet another ES6 solution that I liked better after not being happy with a few thoughts above.

https://codepen.io/902Labs/pen/mxdxRv?editors=0010#0

const camelize = (str) => str
    .split(' ')
    .map(([first, ...theRest]) => (
        `${first.toUpperCase()}${theRest.join('').toLowerCase()}`)
    )
    .join(' ');
user169251
  • 39
  • 2
  • 6