remove whitespaces between and after brackets - in one regex (javascript) - javascript

Remove whitespaces between and after brackets.
Can this be written in one line (now I have two)?
function removeSpaceAfterBeforeBrackets(str) {
str = str.replace(/\s*\(\s*/gi, "(");
str = str.replace(/\s*\)\s*/gi, ")");
return str;
}

You could capture the white space before and after the parenthesis and the parenthesis itself using an or ([()]) in a group and use only the captured parenthesis in the replace.
In this example that would be group 2 $2
function removeSpaceAfterBeforeBrackets(str) {
return str.replace(/(\s*)([()])(\s*)/gi, "$2");
}
console.log(removeSpaceAfterBeforeBrackets("adfdfdf ( fdf ) ljlkjljk"));
console.log(removeSpaceAfterBeforeBrackets("adfdfdf ( fdf ) ljlkjlj( ( (()) ) ))) (( (k"));

You can do like this :-
function removeSpaceAfterBeforeBrackets(str) {
str = str.replace(/\s*\(\s*/gi|/\s*\)\s*/gi , "");
return str;
}

function removeSpaceAfterBeforeBrackets(str) {
str = str.replace(/\s*[\)|\(]\s*/gi, function(x){
return x.indexOf(')') > -1 ? ')' : '(';
});
return str;
}
or ES6:
function removeSpaceAfterBeforeBrackets(str) {
str = str.replace(/\s*[\)|\(]\s*/gi, x => x.indexOf(')') > -1 ? ')' : '(')
return str;
}

You need to use the special replacement patterns of replace method, as explained here:
function removeSpaceAfterBeforeBrackets(str) {
str = str.replace(/\s+([()])\s+/g, "$1");
return str;
}
This will replace the whole regex match with the capturing group, which in this case includes only the parenthesis characters.
Here's an instant test:
var regex = /\s+([()])\s+/g;
var input = "aaa a ( b bb b ) ccc c ( ddd";
console.log(input.replace(regex, "$1"));

Related

Is There any any javascript (js) function for capitalizing string? [duplicate]

I'm trying to write a function that capitalizes the first letter of every word in a string (converting the string to title case).
For instance, when the input is "I'm a little tea pot", I expect "I'm A Little Tea Pot" to be the output. However, the function returns "i'm a little tea pot".
This is my code:
function titleCase(str) {
var splitStr = str.toLowerCase().split(" ");
for (var i = 0; i < splitStr.length; i++) {
if (splitStr.length[i] < splitStr.length) {
splitStr[i].charAt(0).toUpperCase();
}
str = splitStr.join(" ");
}
return str;
}
console.log(titleCase("I'm a little tea pot"));
You are not assigning your changes to the array again, so all your efforts are in vain. Try this:
function titleCase(str) {
var splitStr = str.toLowerCase().split(' ');
for (var i = 0; i < splitStr.length; i++) {
// You do not need to check if i is larger than splitStr length, as your for does that for you
// Assign it back to the array
splitStr[i] = splitStr[i].charAt(0).toUpperCase() + splitStr[i].substring(1);
}
// Directly return the joined string
return splitStr.join(' ');
}
document.write(titleCase("I'm a little tea pot"));
You are making complex a very easy thing. You can add this in your CSS:
.capitalize {
text-transform: capitalize;
}
In JavaScript, you can add the class to an element
document.getElementById("element").className = "capitalize";
ECMAScript 6 version:
const toTitleCase = (phrase) => {
return phrase
.toLowerCase()
.split(' ')
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
.join(' ');
};
let result = toTitleCase('maRy hAd a lIttLe LaMb');
console.log(result);
Shortest One Liner (also extremely fast):
text.replace(/(^\w|\s\w)/g, m => m.toUpperCase());
Explanation:
^\w : first character of the string
| : or
\s\w : first character after whitespace
(^\w|\s\w) Capture the pattern.
g Flag: Match all occurrences.
If you want to make sure the rest is in lowercase:
text.replace(/(^\w|\s\w)(\S*)/g, (_,m1,m2) => m1.toUpperCase()+m2.toLowerCase())
Example usage:
const toTitleCase = str => str.replace(/(^\w|\s\w)(\S*)/g, (_,m1,m2) => m1.toUpperCase()+m2.toLowerCase())
console.log(toTitleCase("heLLo worLd"));
I think this way should be faster; cause it doesn't split string and join it again; just using regex.
var str = text.toLowerCase().replace(/(^\w{1})|(\s{1}\w{1})/g, match => match.toUpperCase());
Explanation:
(^\w{1}): match first char of string
|: or
(\s{1}\w{1}): match one char that came after one space
g: match all
match => match.toUpperCase(): replace with can take function, so; replace match with upper case match
If you can use a third-party library then Lodash has a helper function for you.
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'
<script src="https://cdn.jsdelivr.net/lodash/4.17.3/lodash.min.js"></script>
In ECMAScript 6, a one-line answer using the arrow function:
const captialize = words => words.split(' ').map( w => w.substring(0,1).toUpperCase()+ w.substring(1)).join(' ')
ECMAScript 6 version:
title
.split(/ /g).map(word =>
`${word.substring(0,1).toUpperCase()}${word.substring(1)}`)
.join(" ");
𝗙𝗮𝘀𝘁𝗲𝘀𝘁 𝗦𝗼𝗹𝘂𝘁𝗶𝗼𝗻 𝗙𝗼𝗿 𝗟𝗮𝘁𝗶𝗻-𝗜 𝗖𝗵𝗮𝗿𝗮𝗰𝘁𝗲𝗿𝘀
You could simply use a regular expression function to change the capitalization of each letter. With V8 JIST optimizations, this should prove to be the fast and memory efficient.
// Only works on Latin-I strings
'tHe VeRy LOOong StRINg'.replace(/\b[a-z]|['_][a-z]|\B[A-Z]/g, function(x){return x[0]==="'"||x[0]==="_"?x:String.fromCharCode(x.charCodeAt(0)^32)})
Or, as a function:
// Only works for Latin-I strings
var fromCharCode = String.fromCharCode;
var firstLetterOfWordRegExp = /\b[a-z]|['_][a-z]|\B[A-Z]/g;
function toLatin1UpperCase(x){ // avoid frequent anonymous inline functions
var charCode = x.charCodeAt(0);
return charCode===39 ? x : fromCharCode(charCode^32);
}
function titleCase(string){
return string.replace(firstLetterOfWordRegExp, toLatin1UpperCase);
}
According to this benchmark, the code is over 33% faster than the next best solution in Chrome.
𝗗𝗲𝗺𝗼
<textarea id="input" type="text">I'm a little tea pot</textarea><br /><br />
<textarea id="output" type="text" readonly=""></textarea>
<script>
(function(){
"use strict"
var fromCode = String.fromCharCode;
function upper(x){return x[0]==="'"?x:fromCode(x.charCodeAt(0) ^ 32)}
(input.oninput = function(){
output.value = input.value.replace(/\b[a-z]|['_][a-z]|\B[A-Z]/g, upper);
})();
})();
</script>
text-transform: capitalize;
CSS has got it :)
Also a good option (particularly if you're using freeCodeCamp):
function titleCase(str) {
var wordsArray = str.toLowerCase().split(/\s+/);
var upperCased = wordsArray.map(function(word) {
return word.charAt(0).toUpperCase() + word.substr(1);
});
return upperCased.join(" ");
}
I usually prefer not to use regexp because of readability and also I try to stay away from loops. I think this is kind of readable.
function capitalizeFirstLetter(string) {
return string && string.charAt(0).toUpperCase() + string.substring(1);
};
This routine will handle hyphenated words and words with apostrophe.
function titleCase(txt) {
var firstLtr = 0;
for (var i = 0;i < text.length;i++) {
if (i == 0 &&/[a-zA-Z]/.test(text.charAt(i)))
firstLtr = 2;
if (firstLtr == 0 &&/[a-zA-Z]/.test(text.charAt(i)))
firstLtr = 2;
if (firstLtr == 1 &&/[^a-zA-Z]/.test(text.charAt(i))){
if (text.charAt(i) == "'") {
if (i + 2 == text.length &&/[a-zA-Z]/.test(text.charAt(i + 1)))
firstLtr = 3;
else if (i + 2 < text.length &&/[^a-zA-Z]/.test(text.charAt(i + 2)))
firstLtr = 3;
}
if (firstLtr == 3)
firstLtr = 1;
else
firstLtr = 0;
}
if (firstLtr == 2) {
firstLtr = 1;
text = text.substr(0, i) + text.charAt(i).toUpperCase() + text.substr(i + 1);
}
else {
text = text.substr(0, i) + text.charAt(i).toLowerCase() + text.substr(i + 1);
}
}
}
titleCase("pAt o'Neil's");
// returns "Pat O'Neil's";
You can use modern JS syntax which can make your life much easier. Here is my code snippet for the given problem:
const capitalizeString = string => string.split(' ').map(item => item.replace(item.charAt(0), item.charAt(0).toUpperCase())).join(' ');
capitalizeString('Hi! i am aditya shrivastwa')
function LetterCapitalize(str) {
return str.split(" ").map(item=>item.substring(0,1).toUpperCase()+item.substring(1)).join(" ")
}
let cap = (str) => {
let arr = str.split(' ');
arr.forEach(function(item, index) {
arr[index] = item.replace(item[0], item[0].toUpperCase());
});
return arr.join(' ');
};
console.log(cap("I'm a little tea pot"));
Fast Readable Version see benchmark http://jsben.ch/k3JVz
ES6 syntax
const captilizeAllWords = (sentence) => {
if (typeof sentence !== "string") return sentence;
return sentence.split(' ')
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
.join(' ');
}
captilizeAllWords('Something is going on here')
Or it can be done using replace(), and replace each word's first letter with its "upperCase".
function titleCase(str) {
return str.toLowerCase().split(' ').map(function(word) {
return word.replace(word[0], word[0].toUpperCase());
}).join(' ');
}
titleCase("I'm a little tea pot");
Here a simple one-liner
const ucFirst = t => t.replace(/(^|\s)[A-Za-zÀ-ÖØ-öø-ÿ]/g, c => c.toUpperCase());
Note that it only changes case of first letter of every word, you might want to use it as so:
console.log(ucFirst('foO bAr'));
// FoO BAr
console.log(ucFirst('foO bAr'.toLowerCase()));
// Foo Bar
// works with accents too
console.log(ucFirst('éfoO bAr'));
// ÉfoO BAr
Or based on String.prototype here is one that handles several modes:
String.prototype.ucFirst = function (mode = 'eachWord') {
const modes = {
eachWord: /(^|\s)[A-Za-zÀ-ÖØ-öø-ÿ]/g,
firstWord: /(^|\s)[A-Za-zÀ-ÖØ-öø-ÿ]/,
firstChar: /^[A-Za-zÀ-ÖØ-öø-ÿ]/,
firstLetter: /[A-Za-zÀ-ÖØ-öø-ÿ]/,
};
if (mode in modes) {
return this.replace(modes[mode], c => c.toUpperCase());
} else {
throw `error: ucFirst invalid mode (${mode}). Parameter should be one of: ` + Object.keys(modes).join('|');
}
};
console.log('eachWord', 'foO bAr'.ucFirst());
// FoO BAr
console.log('eachWord', 'foO bAr'.toLowerCase().ucFirst());
// Foo Bar
console.log('firstWord', '1foO bAr'.ucFirst('firstWord'));
// 1foO BAr
console.log('firstChar', '1foO bAr'.ucFirst('firstChar'));
// 1foO bAr
console.log('firstLetter', '1foO bAr'.ucFirst('firstLetter'));
// 1FoO bAr
Edit:
Or based on String.prototype one that handles several modes and an optional second argument to specify word separators (String or RegExp):
String.prototype.ucFirst = function (mode = 'eachWord', wordSeparator = /\s/) {
const letters = /[A-Za-zÀ-ÖØ-öø-ÿ]/;
const ws =
'^|' +
(wordSeparator instanceof RegExp
? '(' + wordSeparator.source + ')'
: // sanitize string for RegExp https://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex#comment52837041_6969486
'[' + wordSeparator.replace(/[[{}()*+?^$|\]\.\\]/g, '\\$&') + ']');
const r =
mode === 'firstLetter'
? letters
: mode === 'firstChar'
? new RegExp('^' + letters.source)
: mode === 'firstWord' || mode === 'eachWord'
? new RegExp(
'(' + ws + ')' + letters.source,
mode === 'eachWord' ? 'g' : undefined
)
: undefined;
if (r) {
return this.replace(r, (c) => c.toUpperCase());
} else {
throw `error: ucFirst invalid mode (${mode}). Parameter should be one of: firstLetter|firstChar|firstWord|eachWord`;
}
};
console.log("mike o'hara".ucFirst('eachWord', " \t\r\n\f\v'"));
// Mike O'Hara
console.log("mike o'hara".ucFirst('eachWord', /[\s']/));
// Mike O'Hara
The function below does not change any other part of the string than trying to convert all the first letters of all words (i.e. by the regex definition \w+) to uppercase.
That means it does not necessarily convert words to Titlecase, but does exactly what the title of the question says: "Capitalize First Letter Of Each Word In A String - JavaScript"
Don't split the string
determine each word by the regex \w+ that is equivalent to [A-Za-z0-9_]+
apply function String.prototype.toUpperCase() only to the first character of each word.
function first_char_to_uppercase(argument) {
return argument.replace(/\w+/g, function(word) {
return word.charAt(0).toUpperCase() + word.slice(1);
});
}
Examples:
first_char_to_uppercase("I'm a little tea pot");
// "I'M A Little Tea Pot"
// This may look wrong to you, but was the intended result for me
// You may wanna extend the regex to get the result you desire, e.g., /[\w']+/
first_char_to_uppercase("maRy hAd a lIttLe LaMb");
// "MaRy HAd A LIttLe LaMb"
// Again, it does not convert words to Titlecase
first_char_to_uppercase(
"ExampleX: CamelCase/UPPERCASE&lowercase,exampleY:N0=apples"
);
// "ExampleX: CamelCase/UPPERCASE&Lowercase,ExampleY:N0=Apples"
first_char_to_uppercase("…n1=orangesFromSPAIN&&n2!='a sub-string inside'");
// "…N1=OrangesFromSPAIN&&N2!='A Sub-String Inside'"
first_char_to_uppercase("snake_case_example_.Train-case-example…");
// "Snake_case_example_.Train-Case-Example…"
// Note that underscore _ is part of the RegEx \w+
first_char_to_uppercase(
"Capitalize First Letter of each word in a String - JavaScript"
);
// "Capitalize First Letter Of Each Word In A String - JavaScript"
Edit 2019-02-07: If you want actual Titlecase (i.e. only the first letter uppercase all others lowercase):
function titlecase_all_words(argument) {
return argument.replace(/\w+/g, function(word) {
return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
});
}
Examples showing both:
test_phrases = [
"I'm a little tea pot",
"maRy hAd a lIttLe LaMb",
"ExampleX: CamelCase/UPPERCASE&lowercase,exampleY:N0=apples",
"…n1=orangesFromSPAIN&&n2!='a sub-string inside'",
"snake_case_example_.Train-case-example…",
"Capitalize First Letter of each word in a String - JavaScript"
];
for (el in test_phrases) {
let phrase = test_phrases[el];
console.log(
phrase,
"<- input phrase\n",
first_char_to_uppercase(phrase),
"<- first_char_to_uppercase\n",
titlecase_all_words(phrase),
"<- titlecase_all_words\n "
);
}
// I'm a little tea pot <- input phrase
// I'M A Little Tea Pot <- first_char_to_uppercase
// I'M A Little Tea Pot <- titlecase_all_words
// maRy hAd a lIttLe LaMb <- input phrase
// MaRy HAd A LIttLe LaMb <- first_char_to_uppercase
// Mary Had A Little Lamb <- titlecase_all_words
// ExampleX: CamelCase/UPPERCASE&lowercase,exampleY:N0=apples <- input phrase
// ExampleX: CamelCase/UPPERCASE&Lowercase,ExampleY:N0=Apples <- first_char_to_uppercase
// Examplex: Camelcase/Uppercase&Lowercase,Exampley:N0=Apples <- titlecase_all_words
// …n1=orangesFromSPAIN&&n2!='a sub-string inside' <- input phrase
// …N1=OrangesFromSPAIN&&N2!='A Sub-String Inside' <- first_char_to_uppercase
// …N1=Orangesfromspain&&N2!='A Sub-String Inside' <- titlecase_all_words
// snake_case_example_.Train-case-example… <- input phrase
// Snake_case_example_.Train-Case-Example… <- first_char_to_uppercase
// Snake_case_example_.Train-Case-Example… <- titlecase_all_words
// Capitalize First Letter of each word in a String - JavaScript <- input phrase
// Capitalize First Letter Of Each Word In A String - JavaScript <- first_char_to_uppercase
// Capitalize First Letter Of Each Word In A String - Javascript <- titlecase_all_words
function titleCase(str) {
var myString = str.toLowerCase().split(' ');
for (var i = 0; i < myString.length; i++) {
var subString = myString[i].split('');
for (var j = 0; j < subString.length; j++) {
subString[0] = subString[0].toUpperCase();
}
myString[i] = subString.join('');
}
return myString.join(' ');
}
TypeScript fat arrow FTW
export const formatTitleCase = (string: string) =>
string
.toLowerCase()
.split(" ")
.map((word) => word.charAt(0).toUpperCase() + word.substring(1))
.join(" ");
Here's how you could do it with the map function basically, it does the same as the accepted answer but without the for-loop. Hence, saves you few lines of code.
function titleCase(text) {
if (!text) return text;
if (typeof text !== 'string') throw "invalid argument";
return text.toLowerCase().split(' ').map(value => {
return value.charAt(0).toUpperCase() + value.substring(1);
}).join(' ');
}
console.log(titleCase("I'm A little tea pot"));
A more compact (and modern) rewrite of #somethingthere's proposed solution:
let titleCase = (str => str.toLowerCase().split(' ').map(
c => c.charAt(0).toUpperCase() + c.substring(1)).join(' '));
document.write(titleCase("I'm an even smaller tea pot"));
Below is another way to capitalize the first alphabet of each word in a string.
Create a custom method for a String object by using prototype.
String.prototype.capitalize = function() {
var c = '';
var s = this.split(' ');
for (var i = 0; i < s.length; i++) {
c+= s[i].charAt(0).toUpperCase() + s[i].slice(1) + ' ';
}
return c;
}
var name = "john doe";
document.write(name.capitalize());
This is a perfect example of using modern javascript practices to improve readability. Have not yet seen a reduce version here, but this is what i use. Its both a curried one-liner and very readable
sentence
.trim().toLowerCase()
.split(' ')
.reduce((sentence, word) => `${sentence} ${word[0].toUpperCase()}${word.substring(1)}`, '')
.trim()
With Regex and handling special characters like ñ with multiple spaces in between : /(^.|\s+.)/g
let text = "ñora ñora"
console.log(text.toLowerCase().replace(/(^.|\s+.)/g, m => m.toUpperCase()))
Raw code:
function capi(str) {
var s2 = str.trim().toLowerCase().split(' ');
var s3 = [];
s2.forEach(function(elem, i) {
s3.push(elem.charAt(0).toUpperCase().concat(elem.substring(1)));
});
return s3.join(' ');
}
capi('JavaScript string exasd');
I used replace() with a regular expression:
function titleCase(str) {
var newStr = str.toLowerCase().replace(/./, (x) => x.toUpperCase()).replace(/[^']\b\w/g, (y) => y.toUpperCase());
console.log(newStr);
}
titleCase("I'm a little tea pot")
A complete and simple solution goes here:
String.prototype.replaceAt=function(index, replacement) {
return this.substr(0, index) + replacement+ this.substr(index
+ replacement.length);
}
var str = 'k j g u i l p';
function capitalizeAndRemoveMoreThanOneSpaceInAString() {
for(let i = 0; i < str.length-1; i++) {
if(str[i] === ' ' && str[i+1] !== '')
str = str.replaceAt(i+1, str[i+1].toUpperCase());
}
return str.replaceAt(0, str[0].toUpperCase()).replace(/\s+/g, ' ');
}
console.log(capitalizeAndRemoveMoreThanOneSpaceInAString(str));

Capitalize the string after hypen in javascript

I would like to know how to capitalize the first letter after hypen in a string using javascript. If no hypen str should in lowercase
var result = capitalize("js-script");
function capitalize(str){
return str.split("-")[1].charAt(0).toUpperCase()+ str.slice(1);
}
Expected Output:
js-script => js-Script
tom => tom
Consider using a regular expression instead - match a - and an alphabetical character, and replace with a - and that word character, capitalized:
const capitalize = (str) => str.replace(/-([a-z])/g, (_, char) => '-' + char.toUpperCase());
console.log(capitalize("js-script"));
console.log(capitalize("foo-bar-baz"));
To fix your original code, if there's only going to be one - in the input, you need to save the rest of the characters in the part after the - (not just the charAt(0)):
function capitalize(str) {
if (!str.includes('-')) {
return str;
}
const [before, after] = str.split("-");
return before + '-' + after.charAt(0).toUpperCase() + after.slice(1);
}
console.log(capitalize('foo-bar'));
console.log(capitalize('foo'));
You can use regex and look behind to do this:
console.log(capitalize("js-script"));
function capitalize(str){
return str.replace(/(?<=-)\w/g, (text) => text.toUpperCase());
}
You can simply use regex and replace method
-[a-z]
- - match character -
[a-z] - match any character from a to z
function capitalize(str){
return typeof str === 'string' ? str.replace(/-([a-z])/gi,(m,g1)=> `-${g1.toUpperCase()}`) : str
}
console.log(capitalize("js-script"))
console.log( capitalize("tom"))
You can do this,
function capitalize(str){
let arrSplit = str.split("-")
let joinArray = [];
for(var i=0;i<arrSplit.length;i++){
if(i==0){
joinArray.push(arrSplit[i]);
}else{
joinArray.push(arrSplit[i].charAt(0).toUpperCase()+arrSplit[i].slice(1));
}
}
return joinArray.join("-",)
}
console.log(capitalize("js-script"))
console.log(capitalize("js-script-again"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Replace characters using Regex positive/negative lookahead?

I have this string :
var a='abc123#xyz123';
I want to build 2 regexes replace functions which :
1) Replace all characters that do have a future '#' - with '*' (not including '#')
so the result should look like :
'******#xyz123'
2) Replace all characters that do not have a future '#' - with '*' (not including '#')
so the result should look like :
'abc123#******'
What have I tried :
For the positive lookahead :
var a='abc123#xyz123';
alert(a.replace(/(.+(?=#))+/ig,'*')); //*#xyz123 --wrong result since it is greedy...
Question :
How can I make my regexes work as expected ?
First part using lookahead:
repl = a.replace(/.(?=[^#]*#)/g, "*");
//=> "******#xyz123"
Explanation:
This regex finds any character that is followed by # using lookahead and replaced that with *.
Second part using replace callback:
repla = a.replace(/#(.*)$/, function(m, t) { return m[0] + t.replace(/./g, '*'); } );
//=> abc123#******
Explanation:
This code finds text after #. Inside the callback function is replaces every character with asterisk.
You can use indexOf and substr for this instead:
function maskBeforeAfter(before, str, character, maskCharacter) {
character = character || '#';
maskCharacter = maskCharacter || '*';
var characterPosition = str.indexOf(character);
if (characterPosition > -1) {
var mask = '';
if (before) {
for (var i = 0; i < characterPosition; i++) {
mask += maskCharacter;
}
return mask + str.substr(characterPosition);
} else {
for (var i = 0; i < str.length - characterPosition - 1; i++) {
mask += maskCharacter;
}
return str.substr(0, characterPosition + 1) + mask;
}
}
return str;
}
function maskBefore(str, character, maskCharacter) {
return maskBeforeAfter(true, str, character, maskCharacter);
}
function maskAfter(str, character, maskCharacter) {
return maskBeforeAfter(false, str, character, maskCharacter);
}
> var a = 'abc12345#xyz123';
> maskBefore(a);
"********#xyz123"
> maskAfter(a);
"abc12345#******"
If you insist on a simple regex:
The first one is already answered. The second can be written similarly:
a.replace(/[^#](?![^#]*#)/g, '*')
(?![^#]*#) is a negative lookahead that checks that there isn't a pound after the current character.
[^#] also checks that the current character isn't a pound. (we could have also used /(?![^#]*#)./g, but it is less pretty.
A positive option is:
a.replace(/[^#](?=[^#]*$)/g, '*');
this is very similar to the first one: (?=[^#]*$) checks that we have only non-pounds ahead, until the end of the string.
In both of this options, all characters in strings with no pounds will be replaces: "abcd" -> "****"

Remove trailing character(s) from string in Javascript

What is an acceptable way to remove a particular trailing character from a string?
For example if I had a string:
> "item,"
And I wanted to remove trailing ','s only if they were ','s?
Thanks!
Use a simple regular expression:
var s = "item,";
s = s.replace(/,+$/, "");
if(myStr.charAt( myStr.length-1 ) == ",") {
myStr = myStr.slice(0, -1)
}
A function to trim any trailing characters would be:
function trimTrailingChars(s, charToTrim) {
var regExp = new RegExp(charToTrim + "+$");
var result = s.replace(regExp, "");
return result;
}
function test(input, charToTrim) {
var output = trimTrailingChars(input, charToTrim);
console.log('input:\n' + input);
console.log('output:\n' + output);
console.log('\n');
}
test('test////', '/');
test('///te/st//', '/');
This will remove trailing non-alphanumeric characters.
const examples = ["abc", "abc.", "...abc", ".abc1..!##", "ab12.c"];
examples.forEach(ex => console.log(ex.replace(/\W+$/, "")));
// Output:
abc
abc
...abc
.abc1
ab12.c

How to convert "camelCase" to "Camel Case"?

I’ve been trying to get a JavaScript regex command to turn something like "thisString" into "This String" but the closest I’ve gotten is replacing a letter, resulting in something like "Thi String" or "This tring". Any ideas?
To clarify I can handle the simplicity of capitalizing a letter, I’m just not as strong with RegEx, and splitting "somethingLikeThis" into "something Like This" is where I’m having trouble.
"thisStringIsGood"
// insert a space before all caps
.replace(/([A-Z])/g, ' $1')
// uppercase the first character
.replace(/^./, function(str){ return str.toUpperCase(); })
displays
This String Is Good
(function() {
const textbox = document.querySelector('#textbox')
const result = document.querySelector('#result')
function split() {
result.innerText = textbox.value
// insert a space before all caps
.replace(/([A-Z])/g, ' $1')
// uppercase the first character
.replace(/^./, (str) => str.toUpperCase())
};
textbox.addEventListener('input', split);
split();
}());
#result {
margin-top: 1em;
padding: .5em;
background: #eee;
white-space: pre;
}
<div>
Text to split
<input id="textbox" value="thisStringIsGood" />
</div>
<div id="result"></div>
I had an idle interest in this, particularly in handling sequences of capitals, such as in xmlHTTPRequest. The listed functions would produce "Xml H T T P Request" or "Xml HTTPRequest", mine produces "Xml HTTP Request".
function unCamelCase (str){
return str
// insert a space between lower & upper
.replace(/([a-z])([A-Z])/g, '$1 $2')
// space before last upper in a sequence followed by lower
.replace(/\b([A-Z]+)([A-Z])([a-z])/, '$1 $2$3')
// uppercase the first character
.replace(/^./, function(str){ return str.toUpperCase(); })
}
There's also a String.prototype version in a gist.
This can be concisely done with regex lookahead (live demo):
function splitCamelCaseToString(s) {
return s.split(/(?=[A-Z])/).join(' ');
}
(I thought that the g (global) flag was necessary, but oddly enough, it isn't in this particular case.)
Using lookahead with split ensures that the matched capital letter is not consumed and avoids dealing with a leading space if UpperCamelCase is something you need to deal with. To capitalize the first letter of each, you can use:
function splitCamelCaseToString(s) {
return s.split(/(?=[A-Z])/).map(function(p) {
return p.charAt(0).toUpperCase() + p.slice(1);
}).join(' ');
}
The map array method is an ES5 feature, but you can still use it in older browsers with some code from MDC. Alternatively, you can iterate over the array elements using a for loop.
I think this should be able to handle consecutive uppercase characters as well as simple camelCase.
For example: someVariable => someVariable, but ABCCode != A B C Code.
The below regex works on your example but also the common example of representing abbreviations in camcelCase.
"somethingLikeThis"
.replace(/([a-z])([A-Z])/g, '$1 $2')
.replace(/([A-Z])([a-z])/g, ' $1$2')
.replace(/\ +/g, ' ') => "something Like This"
"someVariableWithABCCode"
.replace(/([a-z])([A-Z])/g, '$1 $2')
.replace(/([A-Z])([a-z])/g, ' $1$2')
.replace(/\ +/g, ' ') => "some Variable With ABC Code"
You could also adjust as above to capitalize the first character.
Lodash handles this nicely with _.startCase()
function spacecamel(s){
return s.replace(/([a-z])([A-Z])/g, '$1 $2');
}
spacecamel('somethingLikeThis')
// returned value: something Like This
A solution that handles numbers as well:
function capSplit(str){
return str.replace(
/(^[a-z]+)|[0-9]+|[A-Z][a-z]+|[A-Z]+(?=[A-Z][a-z]|[0-9])/g,
function(match, first){
if (first) match = match[0].toUpperCase() + match.substr(1);
return match + ' ';
}
)
}
Tested here [JSFiddle, no library. Not tried IE]; should be pretty stable.
Try this solution here -
var value = "myCamelCaseText";
var newStr = '';
for (var i = 0; i < value.length; i++) {
if (value.charAt(i) === value.charAt(i).toUpperCase()) {
newStr = newStr + ' ' + value.charAt(i)
} else {
(i == 0) ? (newStr += value.charAt(i).toUpperCase()) : (newStr += value.charAt(i));
}
}
return newStr;
If you don't care about older browsers (or don't mind using a fallback reduce function for them), this can split even strings like 'xmlHTTPRequest' (but certainly the likes of 'XMLHTTPRequest' cannot).
function splitCamelCase(str) {
return str.split(/(?=[A-Z])/)
.reduce(function(p, c, i) {
if (c.length === 1) {
if (i === 0) {
p.push(c);
} else {
var last = p.pop(), ending = last.slice(-1);
if (ending === ending.toLowerCase()) {
p.push(last);
p.push(c);
} else {
p.push(last + c);
}
}
} else {
p.push(c.charAt(0).toUpperCase() + c.slice(1));
}
return p;
}, [])
.join(' ');
}
My version
function camelToSpace (txt) {
return txt
.replace(/([^A-Z]*)([A-Z]*)([A-Z])([^A-Z]*)/g, '$1 $2 $3$4')
.replace(/ +/g, ' ')
}
camelToSpace("camelToSpaceWithTLAStuff") //=> "camel To Space With TLA Stuff"
const value = 'camelCase';
const map = {};
let index = 0;
map[index] = [];
for (let i = 0; i < value.length; i++) {
if (i !== 0 && value[i] === value[i].toUpperCase()) {
index = i;
map[index] = [];
}
if (i === 0) {
map[index].push(value[i].toUpperCase());
} else {
map[index].push(value[i]);
}
}
let resultArray = [];
Object.keys(map).map(function (key, index) {
resultArray = [...resultArray, ' ', ...map[key]];
return resultArray;
});
console.log(resultArray.join(''));
Not regex, but useful to know plain and old techniques like this:
var origString = "thisString";
var newString = origString.charAt(0).toUpperCase() + origString.substring(1);

Categories