Blowsie
Blowsie

Reputation: 40535

Convert string to Pascal Case (aka UpperCamelCase) in Javascript

Id like to know how I can covert a string into a pascal case string in javascript (& most probally regex).

Conversion Examples:

Check this link for further info on Pascal Case

Upvotes: 52

Views: 101321

Answers (8)

kalicki2k
kalicki2k

Reputation: 581

Here's my suggestion:

function toPascalCase(string) {
  return string
    .replace(/([a-z])([A-Z])/g, '$1 $2') // Splits camelCase words into separate words
    .replace(/[-_]+|[^\p{L}\p{N}]/gu, ' ') // Replaces dashes, underscores, and special characters with spaces
    .toLowerCase() // Converts the entire string to lowercase
    .replace(/(?:^|\s)(\p{L})/gu, (_, letter) => letter.toUpperCase()) // Capitalizes the first letter of each word
    .replace(/\s+/g, ''); // Removes all spaces
}

or

String.prototype.toPascalCase = function() {
  return this
    .replace(/([a-z])([A-Z])/g, '$1 $2') // Splits camelCase words into separate words
    .replace(/[-_]+|[^\p{L}\p{N}]/gu, ' ') // Replaces dashes, underscores, and special characters with spaces
    .toLowerCase() // Converts the entire string to lowercase
    .replace(/(?:^|\s)(\p{L})/gu, (_, letter) => letter.toUpperCase()) // Capitalizes the first letter of each word
    .replace(/\s+/g, ''); // Removes all spaces
};

Test cases:

describe('String to pascal case', function() {
  it('should return a pascal cased string', function() {
    chai.assert.equal(toPascalCase('foo bar'), 'FooBar');
    chai.assert.equal(toPascalCase('Foo Bar'), 'FooBar');
    chai.assert.equal(toPascalCase('fooBar'), 'FooBar');
    chai.assert.equal(toPascalCase('FooBar'), 'FooBar');
    chai.assert.equal(toPascalCase('--foo-bar--'), 'FooBar');
    chai.assert.equal(toPascalCase('__FOO_BAR__'), 'FooBar');
    chai.assert.equal(toPascalCase('!--foo-¿?-bar--121-**%'), 'FooBar121');
    chai.assert.equal(toPascalCase('Here i am'), 'HereIAm');
    chai.assert.equal(toPascalCase('FOO BAR'), 'FooBar');
    chai.assert.equal(toPascalCase('FOO BAR ÜÖÄ éèó'), 'FooBarÜöäÉèó');
  });
});

JSFiddle Demo

Upvotes: 42

charounkara
charounkara

Reputation: 21

You may experience difficulties in the solutions in other answers due to different characters in different languages. You can use this method to solve these troubles.

const toPascalCase = (str) => {
  let tempArray = str.split(" ");
  tempArray = tempArray.map(
    (value) => value.charAt(0).toUpperCase() + value.slice(1, value.length)
  );
  return tempArray.join("");
};

Upvotes: 1

SeyyedKhandon
SeyyedKhandon

Reputation: 6093

Simpler version with trim space option:

const toPascalCase = (text, trimSpace=false) => text.split(' ').map((t) => t[0].toUpperCase() + t.slice(1).toLowerCase()).join(trimSpace?'':' ')

Tests:

const toPascalCase = (text, trimSpace=false) => text.split(' ').map((t) => t[0].toUpperCase() + t.slice(1).toLowerCase()).join(trimSpace?'':' ')

console.log(toPascalCase('hello world')); // Output: "Hello World"
console.log(toPascalCase('foo bar baz')); // Output: "Foo Bar Baz"
console.log(toPascalCase('this is a sample text')); // Output: "This Is A Sample Text"

Upvotes: 0

Steve Chambers
Steve Chambers

Reputation: 39404

A one-line Typescript version of this answer, which also handles the string being null/undefined:

const toPascalCase = (s: string | null | undefined) =>
  s ? s.replace(/(\w)(\w*)/g, (_, p, q) => p.toUpperCase() + q.toLowerCase()) : s;

Upvotes: 0

mrienstra
mrienstra

Reputation: 622

function toPascalCase (str) {
  if (/^[a-z\d]+$/i.test(str)) {
    return str.charAt(0).toUpperCase() + str.slice(1);
  }
  return str.replace(
    /([a-z\d])([a-z\d]*)/gi,
    (g0, g1, g2) => g1.toUpperCase() + g2.toLowerCase()
  ).replace(/[^a-z\d]/gi, '');
}

I started with Kobi's answer, and used the Chai tests from kalicki2k's answer to kick the tires.

Crude multilingual support can be added by changing a-z to \p{L}, and adding the u flag:

function toPascalCase (str) {
  if (/^[\p{L}\d]+$/iu.test(str)) {
    return str.charAt(0).toUpperCase() + str.slice(1);
  }
  return str.replace(
    /([\p{L}\d])([\p{L}\d]*)/giu,
    (g0, g1, g2) => g1.toUpperCase() + g2.toLowerCase()
  ).replace(/[^\p{L}\d]/giu, '');
}

Two additional tests that only pass with the unicode-enabled version:

chai.assert.equal(toPascalCase('ça.roule'), 'ÇaRoule');
chai.assert.equal(toPascalCase('добрий-день'), 'ДобрийДень');

Incidentally, the non-unicode version is roughly twice as fast as the unicode-version & kalicki2k's version. Which doesn't really matter, they are all plenty fast.

If you need caching:

const pascalCache = {};
function toPascalCase (str) {
    pascalCache[str] =
        pascalCache[str] ||
        (
            /^[a-z\d]+$/i.test(str) &&
            str.charAt(0).toUpperCase() + str.slice(1)
        ) ||
        str.replace(
            /([a-z\d])([a-z\d]*)/gi,
            (g0, g1, g2) => g1.toUpperCase() + g2.toLowerCase()
        ).replace(/[^a-z\d]/gi, '');

    return pascalCache[str];
}

Caching plus multilingual:

const pascalCache = {};
function toPascalCase (str) {
    pascalCache[str] =
        pascalCache[str] ||
        (
            /^[\p{L}\d]+$/iu.test(str) &&
            str.charAt(0).toUpperCase() + str.slice(1)
        ) ||
        str.replace(
            /([\p{L}\d])([\p{L}\d]*)/giu,
            (g0, g1, g2) => g1.toUpperCase() + g2.toLowerCase()
        ).replace(/[^\p{L}\d]/giu, '');

    return pascalCache[str];
}

These versions appear to be much faster (8x) in a benchmark, but of course that's not a good representation of real-world use.

Upvotes: 2

OLUWATOSIN.A AKINYELE
OLUWATOSIN.A AKINYELE

Reputation: 57

const toPascalCase = (sentence) => sentence
   .toLowerCase()
   .replace(new RegExp(/[-_]+/, 'g'), ' ')
   .replace(new RegExp(/[^\w\s]/, 'g'), '')
   .trim()
   .split(' ')
   .map(word => word[0]
   .toUpperCase()
   .concat(word.slice(1)))
   .join('');

toPascalCase(words);

Upvotes: -2

user2809176
user2809176

Reputation: 1275

In case dash, space and other are string separators one may use lodash.

e.g.

_.upperFirst(_.camelCase('double-barrel')); // => DoubleBarrel

Upvotes: 26

Kobi
Kobi

Reputation: 138017

s = s.replace(/(\w)(\w*)/g,
        function(g0,g1,g2){return g1.toUpperCase() + g2.toLowerCase();});

The regex finds words (here defined using \w - alphanumerics and underscores), and separates them to two groups - first letter and rest of the word. It then uses a function as a callback to set the proper case.

Example: http://jsbin.com/uvase

Alternately, this will also work - a little less regex and more string manipulation:

s = s.replace(/\w+/g,
        function(w){return w[0].toUpperCase() + w.slice(1).toLowerCase();});

I should add this isn't pascal case at all, since you have word barriers (helloworld vs hello-world). Without them, the problem is almost unsolvable, even with a dictionary. This is more commonly called Title Case, though it doesn't handle words like "FBI", "the" or "McDonalds".

Upvotes: 71

Related Questions