Reputation: 40535
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
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ÜöäÉèó');
});
});
Upvotes: 42
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
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
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
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
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
Reputation: 1275
In case dash, space and other are string separators one may use lodash.
e.g.
_.upperFirst(_.camelCase('double-barrel')); // => DoubleBarrel
Upvotes: 26
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