Javascript - Adjusting string to title case logic - javascript

I am attempting to convert my string into title case which I'm able to do successfully. using this method:
title.toLowerCase().split(' ').map(function (s) {
return s.charAt(0).toUpperCase() + s.substring(1);
}).join(' ');
But this current logic applies well for one specific title schema. I am attempting to customize it to work better in different scenarios but when doing so none of them have an effect on the outcome of the title.
For starters as seen in the code snippet below, the word (case) is lower case and that should be capitalized too. It seems to not capitalize the first letter after parentheses.
I also attempt to have an outcome where Tv = TV replace the word and = &. I am approaching this using the .replace method
How can I adjust the code snippet below in order to add these conditions?
let title = "Adjusting the title (case and test) on tv"
titleCase = title.toLowerCase().split(' ').map(function (s) {
return s.charAt(0).toUpperCase() + s.substring(1);
}).join(' ');
titleCase.replace(/ and /ig, ' & ');
titleCase.replace("Tv", "TV")
console.log(titleCase)
My expected outcome is : Adjusting The Title (Case & Test) On TV

letterToCapitalize finds the first occurrence of [a-zA-Z0-9_] in each word you're trying to capitalize (the first suitable letter of).
In your code, you must remember that .replace(...) actually returns a brand new string. It does not modify the string in place (in JavaScript, primitive data-types, of which strings are one, are not modifiable). The problem was you weren't assigning this new string to a variable that you were logging out.
let title = "Adjusting the title (case and test) on tv"
let titleCase = title.toLowerCase().split(' ').map((s) => {
let letterToCapitalize = s.match(/\w/)[0];
return s.replace(letterToCapitalize, letterToCapitalize.toUpperCase())
}).join(' ');
titleCase = titleCase.replace(/and/ig, '&').replace("Tv", "TV");
console.log(titleCase)

solution is:
let title = "Adjusting the title (case and test) on tv";
let titleCase;
titleCase = title.toLowerCase().split(' ').map(function (s) {
return s.charAt(0).toUpperCase() + s.substring(1);
}).join(' ').replace(/ and /ig, ' & ').replace(/Tv/ig, "TV");
console.log(titleCase);

With the below method, all you need to do is to specify the words that should be converted to symbols in the symbol object and the words that need to be all upper case in the allUpperCase array.
let title = "Adjusting the title (case and test) on tv";
let reg = /\w+/g;
// convert all words to titleCase
title = title.replace(reg, (word) => {
return word.charAt(0).toUpperCase() + word.slice(1);
});
// convert words that should be symbols
const symbols = {'and': '&'};
for(symbol of Object.keys(symbols)){
let str = symbol;
title = title.replace(new RegExp(str, 'ig'), symbols[symbol]);
}
// convert all words that need to be allUppercase
const allUpperCase = ['TV'];
allUpperCase.forEach(item => {
title = title.replace(new RegExp(item, 'ig'), found => {
return found.toUpperCase();
});
});
console.log(title);

the solution in 1 line using Regex
const str = 'Adjusting the title (case and test) on tv';
const titleCase = (str) => str.replace(/\b[a-z]/gi, (cahr) => cahr.toUpperCase()).replace(/Tv/gi, 'TV');

this is the solution:
let title = "Adjusting the title (case and test) on tv";
let titleCase;
titleCase = title
.toLowerCase()
.split(" ")
.map(function (s) {
return s.charAt(0) == '(' ? '(' + s.charAt(1).toUpperCase() + s.substring(2) : s.charAt(0).toUpperCase() + s.substring(1);
})
.join(" ")
.replace(/ and /gi, " & ")
.replace(/Tv/gi, "TV");
console.log(titleCase);

Related

JavaScript regex to split camel case string

I have been trying to split a string with space when camel case happens. This is so far I can:
CamelCaseSplit = (inputString) => {
const f = str => str.match(/^[A-Z]?[^A-Z]*|[A-Z][^A-Z]*/g).join('
<CAMEL> ');
return f(inputString);
}
It can handle string likes "camelCase", "simple", "number1Case2".
But fails for "ABCWordDEF" and gives me "A B C Word D E F" instead of "ABC Word DEF".
Also the output of "abcDeF123" should be "abc De F123"
How to properly implement splitting into camel case?
You use Lodash's _.words() (https://lodash.com/docs/4.17.15#words) and say
const _ = require('lodash');
const camelCaseToWords = s => _.words(s).join(' ');
You can use
(?<=[a-z\d])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])
To replace with a space. See the regex demo. Details:
(?<=[a-z\d])(?=[A-Z]) - a location between a lowercase letter or a digit, and a an uppercase letter
| - or
(?<=[A-Z])(?=[A-Z][a-z]) - a location between an uppercase letter and a sequence of an uppercase letter + a lowercase letter.
See the JavaScript demo:
CamelCaseSplit = (inputString) => {
const f = str => str.replace(/(?<=[a-z\d])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])/g, ' ');
return f(inputString);
}
const texts = ['camelCase','simple','number1Case2','ABCWordDEF','abcDeF123'];
for (const s of texts) {
console.log(s, '->', CamelCaseSplit(s))
}

How to get the characters / words that lie on both sides, between which our selected character fall?

Let's consider a string str which is defined as :
const str = " 'I am going' - 'I' "
and a function calc() which can be used as :
console.log( calc(str) ) // => am going
So, I decided to make the calc() using regex ! So here is what I thought about.
const calc = (str) => {
const reg = // Not understanding how to get the strings between which '-' falls
str = str.replace(reg, function(_, a) {
const b = remove(a[0], a[1])
return b
})
return str
}
remove() is a function for removing words from string, I made. You can freely modify my code if there is anything incorrect. It's an example how I imagined. So, please help me completing my function !
You could split the string at - and get the content within '' suing match. Then, create a dynamic regex using the RegExp constructor and replace all the instance of second match from the first match
function calc(str) {
const [first, second] = str.split(/\s*-\s*/)
.map(s => s.match(/'([^']+)'/)[1])
return first.replace(new RegExp(second, "g"), '')
}
console.log(calc("'I am going' - 'I'"))
console.log(calc("'Remove this from this string' - 'this'"))
If matchAll is supported in your environment, you could also:
const [first, second] = Array.from(str.matchAll(/'([^']+)'/g), ([,m]) => m)

Replacement by matching in Javascript

I need to match numbers followed by a unit and replace them with digits+underscore+unit using Javascript.
I came out with this code, which does not produce the result I am seeking to achieve.
var x = myFunction("I have 3 billion dollars");
function myFunction(text) {
return text.replace(/(\d+\.?(?:\d{1,2})?) (\bmillion\b|\bbillion\b|\bbillion\b|\bmillions\b|\bbillions\b|\btrillion\b|\btrillions\b|\bmeter\b|\bmeters\b|\bmile\b|\bmiles\b|\%)/gi, function (match) {
return "<span class='highlighted'>" + match[1] + "_" + match[2] + "</span>";
});
}
The above code should return "I have 3_billion dollars" (but it returns _b as far as the substitution is concerned). As I am a newbe with Java, any suggestions would be appreciated.
Edit
Already many useful hints! Here some more imputs examples:
the street is 4.5 miles long
the budget was 430.000 dollars
Simple more clearer example for you
let regex = /\d+ (million|billion|millions|billions|trillion|trillions|meter|meters|mile|miles)/g
let match = "I have 3 billion dollars".match(regex)
let replace = match.map(x => x.split(" ").join("_"))
console.log(replace)
We can use str.replace with your original expression, if it would work:
const regex = /(\d+\.?(?:\d{1,2})?) (\bmillion\b|\bbillion\b|\bbillion\b|\bmillions\b|\bbillions\b|\btrillion\b|\btrillions\b|\bmeter\b|\bmeters\b|\bmile\b|\bmiles\b|\%)/gm;
const str = `3 billion
3 million`;
const subst = `<span class='highlighted'>" $1_$2 "</span>`;
// The substituted value will be contained in the result variable
const result = str.replace(regex, subst);
console.log('Substitution result: ', result);
Also, we can slightly simplify our expression:
(\d+\.?(?:\d{1,2})?) (\bmillions?\b|\bbillions?\b|\btrillions?\b|\bmeters?\b|\bmiles?\b|\%)
const regex = /(\d+\.?(?:\d{1,2})?) (\bmillions?\b|\bbillions?\b|\btrillions?\b|\bmeters?\b|\bmiles?\b|\%)/gm;
const str = `3 billion
3 million
3 %
2 meters`;
const subst = `<span class='highlighted'>" $1_$2 "</span>`;
// The substituted value will be contained in the result variable
const result = str.replace(regex, subst);
console.log(result);
Demo
RegEx
If this expression wasn't desired and you wish to modify it, please visit this link at regex101.com.
RegEx Circuit
jex.im visualizes regular expressions:
match is not an array its a string. You could split it by ' ' join by _
var x = myFunction("I have 3 billion dollars");
function myFunction(text) {
return text.replace(/(\d+\.?(?:\d{1,2})?) (\bmillion\b|\bbillion\b|\bbillion\b|\bmillions\b|\bbillions\b|\btrillion\b|\btrillions\b|\bmeter\b|\bmeters\b|\bmile\b|\bmiles\b|\%)/gi, function (match) {
console.log(match)
return "<span class='highlighted'>" +match.split(' ').join('_')+ "</span>";
});
}
console.log(x)

Javascript - Replace a character inside a substring of a string

I have a string like "this/ is an example abc/def/fgh/uio to give you an example"
I'd like to target the longest word and replace on this substring any "/" by a "+".
I manage to identify the longest word and I would know how to replace ALL "/" by a "+" BUT I don't know how to replace the "/" only in the longest word.
Here's what I've got so far
//identify longest word in string
function longestWord(str) {
var words = str.split(' ');
return words.reduce(longer);
}
function longer(champ, contender) {
return (contender.length > champ.length) ? contender: champ;
}
//purely given an exemple, some strigns won't be exactly like this
var text2 = "this/ is an example abc/def/fgh/uio to give you an example"
if (longestWord(text2) > 30 ) {
text2.replace(/\//g, ' / ');
}
The problem is this will also replace the "/" on the substring "this/", and I don't want that.
How to achieve this?
Your longestWord function returns the longest word in the string, so you can pass that string alone (not a regular expression) as the first argument to .replace, and replace with (the second argument) the /\//g called on that longest word:
function getLongestWord(str) {
var words = str.split(' ');
return words.reduce(longer);
}
function longer(champ, contender) {
return (contender.length > champ.length) ? contender: champ;
}
var text2 = "this/ is an example abc/def/fgh/uio to give you an example"
const longestWord = getLongestWord(text2);
const output = text2.replace(longestWord, longestWord.replace(/\//g, '+'));
console.log(output);
#CertainPermance's solution is far more elegant (and I think performant) than this, but as I'd written the answer I thought I may as well put it in.
It's fairly similar, in truth, though in this instance we get the index of the word and use that to perform the replace, which at the time of writing I thought was necessary. Now looking at the better solution, I realise such a check is not needed, as the longest word in a string will not feature in any other words, so it's easy and safe to simply perform a replace on it.
const data = "this/ is an example abc/def/fgh/uio to give you an example";
const getLongestWordIndex = stringIn => stringIn
.split(' ')
.reduce(
(prev, curr, i) => curr.length > prev.length ? {
index: i,
length: curr.length
} : prev,
{
length: -1,
index: -1
}
).index
const replaceLongestWord = (sentence, replacer) => {
const longestWordIndex = getLongestWordIndex(sentence);
const words = data.split(' ');
return Object.values({
...words,
[longestWordIndex]: replacer(words[longestWordIndex])
}).join(' ')
}
const wordReplaceFunction = word => word.replace(/\//g, '+')
const result = replaceLongestWord(data, wordReplaceFunction);
console.dir(result)

Convert camelCaseText to Title Case Text

How can I convert a string either like 'helloThere' or 'HelloThere' to 'Hello There' in JavaScript?
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".
Of course, in case the first letter is already capital - you would have a spare space to remove.
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.
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
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();
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>
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
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:
[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.
[^A-Z](?=[A-Z]) looks for a non-capital-letter followed by a capital letter. This ends words like myWord and symbols like 99Bottles.
[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!
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;
}
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
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/.
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:
([A-Z]) - matches uppercase letters...
(?=[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:
([a-z]) - matches lowercase letters...
(?=[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"]
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')
})
})
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)
}
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"
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"
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.
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'
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");
}
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(),
'')
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
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
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");
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')
// uppercase the first character
.replace(/^./, str => str.toUpperCase())
.replace(/\s+/g, ' ')
.trim();
}
const input = 'HTTPRequest_ToServer-AndWaiting';
const result = toSpaceCase(input);
console.log(input,'-->', result)
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)
}
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)
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(' ');

Categories

Resources