问题
Is there a simple way to convert a string to title case? E.g. john smith
becomes John Smith
. I\'m not looking for something complicated like John Resig\'s solution, just (hopefully) some kind of one- or two-liner.
回答1:
Try this:
function toTitleCase(str) {
return str.replace(
/\w\S*/g,
function(txt) {
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
}
);
}
<form>
Input:
<br /><textarea name="input" onchange="form.output.value=toTitleCase(this.value)" onkeyup="form.output.value=toTitleCase(this.value)"></textarea>
<br />Output:
<br /><textarea name="output" readonly onclick="select(this)"></textarea>
</form>
回答2:
A slightly more elegant way, adapting Greg Dean's function:
String.prototype.toProperCase = function () {
return this.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
};
Call it like:
"pascal".toProperCase();
回答3:
Try to apply the text-transform CSS style to your controls.
eg: (text-transform: capitalize);
Only use a JS approach when absolutely necessary.
回答4:
Here's my version, IMO it's easy to understand and elegant too.
var str = "foo bar baz"
console.log(
str.split(' ')
.map(w => w[0].toUpperCase() + w.substr(1).toLowerCase())
.join(' ')
)
// returns "Foo Bar Baz"
回答5:
Here’s my function that converts to title case but also preserves defined acronyms as uppercase and minor words as lowercase:
String.prototype.toTitleCase = function() {
var i, j, str, lowers, uppers;
str = this.replace(/([^\W_]+[^\s-]*) */g, function(txt) {
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
});
// Certain minor words should be left lowercase unless
// they are the first or last words in the string
lowers = ['A', 'An', 'The', 'And', 'But', 'Or', 'For', 'Nor', 'As', 'At',
'By', 'For', 'From', 'In', 'Into', 'Near', 'Of', 'On', 'Onto', 'To', 'With'];
for (i = 0, j = lowers.length; i < j; i++)
str = str.replace(new RegExp('\\s' + lowers[i] + '\\s', 'g'),
function(txt) {
return txt.toLowerCase();
});
// Certain words such as initialisms or acronyms should be left uppercase
uppers = ['Id', 'Tv'];
for (i = 0, j = uppers.length; i < j; i++)
str = str.replace(new RegExp('\\b' + uppers[i] + '\\b', 'g'),
uppers[i].toUpperCase());
return str;
}
For example:
"TO LOGIN TO THIS SITE and watch tv, please enter a valid id:".toTitleCase();
// Returns: "To Login to This Site and Watch TV, Please Enter a Valid ID:"
回答6:
I prefer the following over the other answers. It matches only the first letter of each word and capitalises it. Simpler code, easier to read and less bytes. It preserves existing capital letters to prevent distorting acronyms. However you can always call toLowerCase()
on your string first.
function title(str) {
return str.replace(/(^|\s)\S/g, function(t) { return t.toUpperCase() });
}
You can add this to your string prototype which will allow you to 'my string'.toTitle()
as follows:
String.prototype.toTitle = function() {
return this.replace(/(^|\s)\S/g, function(t) { return t.toUpperCase() });
}
回答7:
Without using regex just for reference:
String.prototype.toProperCase = function() {
var words = this.split(' ');
var results = [];
for (var i = 0; i < words.length; i++) {
var letter = words[i].charAt(0).toUpperCase();
results.push(letter + words[i].slice(1));
}
return results.join(' ');
};
console.log(
'john smith'.toProperCase()
)
回答8:
Just in case you are worried about those filler words, you can always just tell the function what not to capitalize.
/**
* @param String str The text to be converted to titleCase.
* @param Array glue the words to leave in lowercase.
*/
var titleCase = function(str, glue){
glue = (glue) ? glue : ['of', 'for', 'and'];
return str.replace(/(\w)(\w*)/g, function(_, i, r){
var j = i.toUpperCase() + (r != null ? r : "");
return (glue.indexOf(j.toLowerCase())<0)?j:j.toLowerCase();
});
};
Hope this helps you out.
edit
If you want to handle leading glue words, you can keep track of this w/ one more variable:
var titleCase = function(str, glue){
glue = !!glue ? glue : ['of', 'for', 'and', 'a'];
var first = true;
return str.replace(/(\w)(\w*)/g, function(_, i, r) {
var j = i.toUpperCase() + (r != null ? r : '').toLowerCase();
var result = ((glue.indexOf(j.toLowerCase()) < 0) || first) ? j : j.toLowerCase();
first = false;
return result;
});
};
回答9:
If regex used in the above solutions is getting you confused, try this code:
function titleCase(str) {
return str.split(' ').map(function(val){
return val.charAt(0).toUpperCase() + val.substr(1).toLowerCase();
}).join(' ');
}
回答10:
var result =
'this is very interesting'.replace(/\b[a-z]/g, (x) => x.toUpperCase())
console.log(result) // This Is Very Interesting
回答11:
You could immediately toLowerCase
the string, and then just toUpperCase
the first letter of each word. Becomes a very simple 1 liner:
function titleCase(str) {
return str.toLowerCase().replace(/\b(\w)/g, s => s.toUpperCase());
}
console.log(titleCase('iron man'));
console.log(titleCase('iNcrEdible hulK'));
回答12:
var toMatch = "john w. smith";
var result = toMatch.replace(/(\w)(\w*)/g, function (_, i, r) {
return i.toUpperCase() + (r != null ? r : "");
}
)
Seems to work... Tested with the above, "the quick-brown, fox? /jumps/ ^over^ the ¡lazy! dog..." and "C:/program files/some vendor/their 2nd application/a file1.txt".
If you want 2Nd instead of 2nd, you can change to /([a-z])(\w*)/g
.
The first form can be simplified as:
function toTitleCase(toTransform) {
return toTransform.replace(/\b([a-z])/g, function (_, initial) {
return initial.toUpperCase();
});
}
回答13:
I made this function which can handle last names (so it's not title case) such as "McDonald" or "MacDonald" or "O'Toole" or "D'Orazio". It doesn't however handle German or Dutch names with "van" or "von" which are often in lower-case... I believe "de" is often lower-case too such as "Robert de Niro". These would still have to be addressed.
function toProperCase(s)
{
return s.toLowerCase().replace( /\b((m)(a?c))?(\w)/g,
function($1, $2, $3, $4, $5) { if($2){return $3.toUpperCase()+$4+$5.toUpperCase();} return $1.toUpperCase(); });
}
回答14:
Try this
String.prototype.toProperCase = function(){
return this.toLowerCase().replace(/(^[a-z]| [a-z]|-[a-z])/g,
function($1){
return $1.toUpperCase();
}
);
};
Example
var str = 'john smith';
str.toProperCase();
回答15:
Try this, shortest way:
str.replace(/(^[a-z])|(\s+[a-z])/g, txt => txt.toUpperCase());
回答16:
ES 6
str.split(' ')
.map(s => s.slice(0, 1).toUpperCase() + s.slice(1).toLowerCase())
.join(' ')
else
str.split(' ').map(function (s) {
return s.slice(0, 1).toUpperCase() + s.slice(1).toLowerCase();
}).join(' ')
回答17:
Most of these answers seem to ignore the possibility of using the word boundary metacharacter (\b). A shorter version of Greg Dean's answer utilizing it:
function toTitleCase(str)
{
return str.replace(/\b\w/g, function (txt) { return txt.toUpperCase(); });
}
Works for hyphenated names like Jim-Bob too.
回答18:
I think the simplest is using css.
function format_str(str) {
str = str.toLowerCase();
return '<span style="text-transform: capitalize">'+ str +'</span>';
}
回答19:
Use /\S+/g
to support diacritics:
function toTitleCase(str) {
return str.replace(/\S+/g, str => str.charAt(0).toUpperCase() + str.substr(1).toLowerCase());
}
console.log(toTitleCase("a city named örebro")); // A City Named Örebro
However: "sunshine (yellow)" ⇒ "Sunshine (yellow)"
回答20:
If you can use third party libraries in your code then lodash has a helper function for us.
https://lodash.com/docs/4.17.3#startCase
_.startCase('foo bar');
// => 'Foo Bar'
_.startCase('--foo-bar--');
// => 'Foo Bar'
_.startCase('fooBar');
// => 'Foo Bar'
_.startCase('__FOO_BAR__');
// => 'FOO BAR'
回答21:
Taking the "lewax00" solution I created this simple solution that force to "w" starting with space or "w" that initiate de word, but is not able to remove the extra intermediate spaces.
"SOFÍA vergara".toLowerCase().replace(/\b(\s\w|^\w)/g, function (txt) { return txt.toUpperCase(); });
The result is "Sofía Vergara".
回答22:
here's another solution using css (and javascript, if the text you want to transform is in uppercase):
html
<span id='text'>JOHN SMITH</span>
js
var str = document.getElementById('text').innerHtml;
var return_text = str.toLowerCase();
css
#text{text-transform:capitalize;}
回答23:
"john f. kennedy".replace(/\b\S/g, t => t.toUpperCase())
回答24:
Here is my function that is taking care of accented characters (important for french !) and that can switch on/off the handling of lowers exceptions. Hope that helps.
String.prototype.titlecase = function(lang, withLowers = false) {
var i, string, lowers, uppers;
string = this.replace(/([^\s:\-'])([^\s:\-']*)/g, function(txt) {
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
}).replace(/Mc(.)/g, function(match, next) {
return 'Mc' + next.toUpperCase();
});
if (withLowers) {
if (lang == 'EN') {
lowers = ['A', 'An', 'The', 'At', 'By', 'For', 'In', 'Of', 'On', 'To', 'Up', 'And', 'As', 'But', 'Or', 'Nor', 'Not'];
}
else {
lowers = ['Un', 'Une', 'Le', 'La', 'Les', 'Du', 'De', 'Des', 'À', 'Au', 'Aux', 'Par', 'Pour', 'Dans', 'Sur', 'Et', 'Comme', 'Mais', 'Ou', 'Où', 'Ne', 'Ni', 'Pas'];
}
for (i = 0; i < lowers.length; i++) {
string = string.replace(new RegExp('\\s' + lowers[i] + '\\s', 'g'), function(txt) {
return txt.toLowerCase();
});
}
}
uppers = ['Id', 'R&d'];
for (i = 0; i < uppers.length; i++) {
string = string.replace(new RegExp('\\b' + uppers[i] + '\\b', 'g'), uppers[i].toUpperCase());
}
return string;
}
回答25:
For those of us who are scared of regular expressions (lol):
function titleCase(str)
{
var words = str.split(" ");
for ( var i = 0; i < words.length; i++ )
{
var j = words[i].charAt(0).toUpperCase();
words[i] = j + words[i].substr(1);
}
return words.join(" ");
}
回答26:
We have been having a discussion back here at the office and we think that trying to automatically correct the way people input names in the current way you want it doing is fraught with possible issues.
We have come up with several cases where different types of auto capitalization fall apart and these are just for English names alone, each language has its own complexities.
Issues with capitalizing the first letter of each name:
• Acronyms such as IBM aren’t allowed to be inputted, would turn into Ibm.
• The Name McDonald would turn into Mcdonald which is incorrect, the same thing is MacDonald too.
• Double barrelled names such as Marie-Tonks would get turned into Marie-tonks.
• Names like O’Connor would turn into O’connor.
For most of these you could write custom rules to deal with it, however, this still has issues with Acronyms as before and you get a new issue:
• Adding in a rule to fix names with Mac such as MacDonald, would the break names such as Macy turning it into MacY.
The only solution we have come up with that is never incorrect is to capitalize every letter which is a brute force method that the DBS appear to also use.
So if you want to automate the process it is as good as impossible to do without a dictionary of every single name and word and how it should be capitlized, If you don't have a rule that covers everything don't use it as it will just annoy your users and prompt people who want to enter their names correctly to go else where.
回答27:
I wanted to add my own answer as I needed a robust toTitleCase
function that takes into account grammar rules listed here (Google recommended article). There are various rules that depend on the length of the input string. Below is the function + unit tests.
The function also consolidates whitespace and removes special characters (modify regex for your needs)
toTitleCase Function
const toTitleCase = (str) => {
const articles = ['a', 'an', 'the'];
const conjunctions = ['for', 'and', 'nor', 'but', 'or', 'yet', 'so'];
const prepositions = [
'with', 'at', 'from', 'into','upon', 'of', 'to', 'in', 'for',
'on', 'by', 'like', 'over', 'plus', 'but', 'up', 'down', 'off', 'near'
];
// The list of spacial characters can be tweaked here
const replaceCharsWithSpace = (str) => str.replace(/[^0-9a-z&/\\]/gi, ' ').replace(/(\s\s+)/gi, ' ');
const capitalizeFirstLetter = (str) => str.charAt(0).toUpperCase() + str.substr(1);
const normalizeStr = (str) => str.toLowerCase().trim();
const shouldCapitalize = (word, fullWordList, posWithinStr) => {
if ((posWithinStr == 0) || (posWithinStr == fullWordList.length - 1)) {
return true;
}
return !(articles.includes(word) || conjunctions.includes(word) || prepositions.includes(word));
}
str = replaceCharsWithSpace(str);
str = normalizeStr(str);
let words = str.split(' ');
if (words.length <= 2) { // Strings less than 3 words long should always have first words capitalized
words = words.map(w => capitalizeFirstLetter(w));
}
else {
for (let i = 0; i < words.length; i++) {
words[i] = (shouldCapitalize(words[i], words, i) ? capitalizeFirstLetter(words[i], words, i) : words[i]);
}
}
return words.join(' ');
}
Unit Tests to Ensure Correctness
import { expect } from 'chai';
import { toTitleCase } from '../../src/lib/stringHelper';
describe('toTitleCase', () => {
it('Capitalizes first letter of each word irrespective of articles, conjunctions or prepositions if string is no greater than two words long', function(){
expect(toTitleCase('the dog')).to.equal('The Dog'); // Capitalize articles when only two words long
expect(toTitleCase('for all')).to.equal('For All'); // Capitalize conjunctions when only two words long
expect(toTitleCase('with cats')).to.equal('With Cats'); // Capitalize prepositions when only two words long
});
it('Always capitalize first and last words in a string irrespective of articles, conjunctions or prepositions', function(){
expect(toTitleCase('the beautiful dog')).to.equal('The Beautiful Dog');
expect(toTitleCase('for all the deadly ninjas, be it so')).to.equal('For All the Deadly Ninjas Be It So');
expect(toTitleCase('with cats and dogs we are near')).to.equal('With Cats and Dogs We Are Near');
});
it('Replace special characters with space', function(){
expect(toTitleCase('[wolves & lions]: be careful')).to.equal('Wolves & Lions Be Careful');
expect(toTitleCase('wolves & lions, be careful')).to.equal('Wolves & Lions Be Careful');
});
it('Trim whitespace at beginning and end', function(){
expect(toTitleCase(' mario & Luigi superstar saga ')).to.equal('Mario & Luigi Superstar Saga');
});
it('articles, conjunctions and prepositions should not be capitalized in strings of 3+ words', function(){
expect(toTitleCase('The wolf and the lion: a tale of two like animals')).to.equal('The Wolf and the Lion a Tale of Two like Animals');
expect(toTitleCase('the three Musketeers And plus ')).to.equal('The Three Musketeers and Plus');
});
});
Please note that I am removing quite a bit of special characters from the strings provided. You will need to tweak the regex to address the requirements of your project.
回答28:
This is based on my solution for FreeCodeCamp's Bonfire "Title Case", which requires you to first convert the given string to all lower case and then convert every character proceeding a space to upper case.
Without using regex:
function titleCase(str) {
return str.toLowerCase().split(' ').map(function(val) { return val.replace(val[0], val[0].toUpperCase()); }).join(' ');
}
回答29:
My simple and easy version to the problem:
function titlecase(str){
var arr=[];
var str1=str.split(' ');
for (var i = 0; i < str1.length; i++) {
var upper= str1[i].charAt(0).toUpperCase()+ str1[i].substr(1);
arr.push(upper);
};
return arr.join(' ');
}
titlecase('my name is suryatapa roy');
回答30:
First, convert your string
into array by splitting it by spaces:
var words = str.split(' ');
Then use array.map to create a new array containing the capitalized words.
var capitalized = words.map(function(word) {
return word.charAt(0).toUpperCase() + word.substring(1, word.length);
});
Then join the new array with spaces:
capitalized.join(" ");
function titleCase(str) {
str = str.toLowerCase(); //ensure the HeLlo will become Hello at the end
var words = str.split(" ");
var capitalized = words.map(function(word) {
return word.charAt(0).toUpperCase() + word.substring(1, word.length);
});
return capitalized.join(" ");
}
console.log(titleCase("I'm a little tea pot"));
NOTE:
This of course has a drawback. This will only capitalize the first letter of every word. By word, this means that it treats every string separated my spaces as 1 word.
Supposedly you have:
str = "I'm a little/small tea pot";
This will produce
I'm A Little/small Tea Pot
compared to the expected
I'm A Little/Small Tea Pot
In that case, using Regex and .replace will do the trick:
with ES6:
const capitalize = str => str.length
? str[0].toUpperCase() +
str.slice(1).toLowerCase()
: '';
const escape = str => str.replace(/./g, c => `\\${c}`);
const titleCase = (sentence, seps = ' _-/') => {
let wordPattern = new RegExp(`[^${escape(seps)}]+`, 'g');
return sentence.replace(wordPattern, capitalize);
};
console.log( titleCase("I'm a little/small tea pot.") );
or without ES6:
function capitalize(str) {
return str.charAt(0).toUpperCase() + str.substring(1, str.length).toLowerCase();
}
function titleCase(str) {
return str.replace(/[^\ \/\-\_]+/g, capitalize);
}
console.log(titleCase("hello/hi world"));
来源:https://stackoverflow.com/questions/196972/convert-string-to-title-case-with-javascript