Reputation: 12399
I have some data I need to format by capitalizing the first letter of each word, and lowercasing the rest. I am using the following :
function toTitleCase(str){
return str.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
}
It works but I need to add exceptions to it, all values being in an array : [USA,U.S.A,7UP,PC,SlimFast,...]
These values are sometimes upper, sometimes lower, sometimes mixed and need to not be modified. Any ideas?
Upvotes: 2
Views: 8385
Reputation: 12399
Solved using the following function.
function toTitleCase(str){
return str.replace(/\w\S*/g, function(txt){
if(['PC','USA','U.S.A'].includes(txt))===-1){
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
} else {
return txt;
}
});
}
name = toTitleCase(name);
Upvotes: 2
Reputation: 13226
It might not be exactly what you need, but the general idea:
- Split/target each word.
- Check if it doesn't match a word in the ignore list (using the
i
flag to ignore capitalization)- If it doesn't, capitalize it,
- If it does, leave it alone.
var s = "UsA bar U.S.A. fOO slimfast bAz",
ignore = ["USA", "U.S.A", "7UP", "PC", "SlimFast"],
regex = new RegExp(ignore.join("|"), 'i'),
result = s.split(' ').map(function(word){
return (regex.test(word)) ? word : capitalize(word);
}).join(' ');
// "UsA Bar U.S.A. Foo slimfast Baz"
function capitalize(s) {
return s.charAt(0).toUpperCase() + s.slice(1).toLowerCase();
}
Upvotes: 1
Reputation: 5343
function toTitleCase(str){
var cantTouchThis = {'USA' : 1, 'U.S.A' : 1, '7UP' : 1, 'PC' : 1, 'SLIMFAST' : 1};
return str.replace(/\w[\S.]*/g, function(txt){return cantTouchThis[txt.toUpperCase()] ? txt : txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
}
the keys is an uppercase of string which you don't want to replace
the values can be anything that evaluates to true
but you may also want to give the only correct casing in value - something like:
function toTitleCase(str){
var cantTouchThis = {'USA' : 'USA', 'U.S.A' : 'USA', '7UP' : '7Up', 'PC' : 'PC', 'SLIMFAST' : 'SlimFast'};
return str.replace(/\w[\S.]*/g, function(txt){return cantTouchThis[txt.toUpperCase()] || txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
}
this way string like:
UsA U.S.A anything slimfast
will become:
USA USA Anything SlimFast
Upvotes: 1
Reputation: 27823
EDIT: It seems i didn't quite understand that the exceptions are entire words. The answer below deals with exceptions being part of the words.
I'm not particularly sure this is the best solution, but you could get an array of matches to your exceptions, then run your function, then replace the matches back.
var exceptions = ['USA','U\.S\.A','7UP','PC','SlimFast']; //escaped strings!
var matcher = new RegExp(exceptions.join('|'), 'gi');
var str = 'tuSalolpCOKyes'; //test string
var matches = str.match(matcher); // extract replacements
var str = toTitleCase(str); // run your function
// replace stuff you didn't want changed
var index = 0;
var str = str.replace(matcher, function() {
return matches[index++];
});
console.log(str); // RESULT: TuSalolpCokyes
// your function
function toTitleCase(str){
return str.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
}
Upvotes: 0
Reputation: 407
What about something along the lines of this:
function toTitleCase(str){
var ignore = inArray(exceptionsArr, str);
if (!ignore) {
return str.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
}
return str;
}
inArray: function(arr, obj) {
return (arr.indexOf(obj) != -1);
},
Alternatively if your str is an entire sentence with the exception words inside it, you can split the str into individual words and then run each word through the above process with a for loop.
Upvotes: 2