I have searched for solution but did not find yet.
I have the following string.
1. hello
2. HELLO
3. hello_world
4. HELLO_WORLD
5. Hello World
I want to convert them to following:
1. Hello
2. Hello
3. HelloWorld
4. HelloWorld
5. HelloWorld
If there is No space and underscore in string just uppercase first and all others to lowercase. If words are separated by underscore or space then Uppercase first letter of each word and remove space and underscore. How can I do this in JavaScript.
Thanks
Here is a regex solution:
First lowercase the string:
str = str.toLowerCase();
Replace all _ and spaces and first characters in a word with upper case character:
str = str.replace(/(?:_| |\b)(\w)/g, function(str, p1) { return p1.toUpperCase()})
DEMO
Update: Less steps ;)
Explanation:
/ // start of regex
(?: // starts a non capturing group
_| |\b // match underscore, space, or any other word boundary character
// (which in the end is only the beginning of the string ^)
) // end of group
( // start capturing group
\w // match word character
) // end of group
/g // and of regex and search the whole string
The value of the capturing group is available as p1 in the function, and the whole expression is replaced by the return value of the function.
You could do something like this:
function toPascalCase(str) {
var arr = str.split(/\s|_/);
for(var i=0,l=arr.length; i<l; i++) {
arr[i] = arr[i].substr(0,1).toUpperCase() +
(arr[i].length > 1 ? arr[i].substr(1).toLowerCase() : "");
}
return arr.join("");
}
You can test it out here, the approach is pretty simple, .split() the string into an array when finding either whitespace or an underscore. Then loop through the array, upper-casing the first letter, lower-casing the rest...then take that array of title-case words and .join() it together into one string again.
function foo(str) {
return $(str.split(/\s|_/)).map(function() {
return this.charAt(0).toUpperCase() + this.slice(1).toLowerCase();
}).get().join("");
}
Working demo: http://jsfiddle.net/KSJe3/3/
(I used Nicks regular expression in the demo)
Edit: Another version of the code - I replaced map() with $.map():
function foo(str) {
return $.map(str.split(/\s|_/), function(word) {
return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
}).join("");
}
Working demo: http://jsfiddle.net/KSJe3/4/
An ES6 / functional update of #NickCraver's answer. As with #NickCraver's answer this function will handle multiple spaces / underscores properly by filtering them out.
const pascalWord = x => x[0].toUpperCase() + x.slice(1).toLowerCase();
const toPascalCase2 = (str) => (
str.split(/\s|_/)
.filter(x => x)
.map(pascalWord)
.join('')
);
const tests = [
'hello',
'HELLO',
'hello_world',
'HELLO_WORLD',
'Hello World',
'HELLO__WORLD__',
'Hello World_',
].map(toPascalCase2).join('<br>');
document.write(tests);
var city = city.replace(/\s+/g,' ') //replace all spaceses to singele speace
city = city.replace(/\b\w/g,city => city .toUpperCase()) //after speace letter convert capital
Related
I'm trying to create a regex that will select the numbers/numbers with commas(if easier, can trim commas later) that do not have a parentheses after and not the numbers inside the parentheses should not be selected either.
Used with the JavaScript's String.match method
Example strings
9(296,178),5,3(123),10
10,9(296,178),2,5,3(123),3(124,125)
10,7,5(296,293,444,1255),3(218),2,4
What i have so far:
/((^\d+[^\(])|(,\d+,)|(,*\d+$))/gm
I tried this in regex101 and underlined the numbers i would like to match and x on the one that should not.
You could start with a substitution to remove all the unwanted parts:
/\d*\(.*?\),?//gm
Demo
This leaves you with
5,10
10,2,5,
10,7,2,4
which makes the matching pretty straight forward:
/(\d+)/gm
If you want it as a single match expression you could use a negative lookbehind:
/(?<!\([\d,]*)(\d+)(?:,|$)/gm
Demo - and here's the same matching expression as a runnable javascript (skeleton code borrowed from Wiktor's answer):
const text = `9(296,178),5,3(123),10
10,9(296,178),2,5,3(123),3(124,125)
10,7,5(296,293,444,1255),3(218),2,4`;
const matches = Array.from(text.matchAll(/(?<!\([\d,]*)(\d+)(?:,|$)/gm), x=>x[1])
console.log(matches);
Here, I'd recommend the so-called "best regex trick ever": just match what you do not need (negative contexts) and then match and capture what you need, and grab the captured items only.
If you want to match integer numbers that are not matched with \d+\([^()]*\) pattern (a number followed with a parenthetical substring), you can match this pattern or match and capture the \d+, one or more digit matching pattern, and then simply grab Group 1 values from matches:
const text = `9(296,178),5,3(123),10
10,9(296,178),2,5,3(123),3(124,125)
10,7,5(296,293,444,1255),3(218),2,4`;
const matches = Array.from(text.matchAll(/\d+\([^()]*\)|(\d+)/g), x=> x[1] ?? "").filter(Boolean)
console.log(matches);
Details:
text.matchAll(/\d+\([^()]*\)|(\d+)/g) - matches one or more digits (\d+) + ( (with \() + any zero or more chars other than ( and ) (with [^()]*) + \) (see \)), or (|) one or more digits captured into Group 1 ((\d+))
Array.from(..., x=> x[1] ?? "") - gets Group 1 value, or, if not assigned, just adds an empty string
.filter(Boolean) - removes empty strings.
Using several replacement regexes
var textA = `9(296,178),5,3(123),10
10,9(296,178),2,5,3(123),3(124,125)
10,7,5(296,293,444,1255),3(218),2,4
`
console.log('A', textA)
var textB = textA.replace(/\(.*?\),?/g, ';')
console.log('B', textB)
var textC = textB.replace(/^\d+|\d+$|\d*;\d*/gm, '')
console.log('C', textC)
var textD = textC.replace(/,+/g, ' ').trim(',')
console.log('D', textD)
With a loop
Here is a solution which splits the lines on comma and loops over the pieces:
var inside = false;
var result = [];
`9(296,178),5,3(123),10
10,9(296,178),2,5,3(123),3(124,125)
10,7,5(296,293,444,1255),3(218),2,4
`.split("\n").map(line => {
let pieceArray = line.split(",")
pieceArray.forEach((piece, k) => {
if (piece.includes('(')) {
inside = true
} else if (piece.includes(')')) {
inside = false
} else if (!inside && k > 0 && k < pieceArray.length-1 && !pieceArray[k-1].includes(')')) {
result.push(piece)
}
})
})
console.log(result)
It does print the expected result: ["5", "7"]
I'm fairly new to JavaScript (and development in general). I wanted to try a challenge from Codewars. The challenge was to process a string through a function that would flip any words that were over 5 characters and return the original string with those flipped words. Here's the code I came up with (It did work!).
//this function turns each word into an array that will get flipped.
let wordFlipper = (word) => {
var splitWord = word.split(''); //convert word to array
var reversedWord = splitWord.reverse(); //flips the indexes for the array
var joinReversedWord = reversedWord.join('').toString(); //turns array back to a string.
return joinReversedWord;
}
function spinWords(phrase){
let finalArray = [];
let wordsToArray = phrase.split(' ');
const processFlipWords = wordsToArray.forEach(word => {
if (word.toString().length > 4) {
var flippedWord = wordFlipper(word); //here's where we call the function wordFlipper()
finalArray.push(flippedWord);
}
else {
finalArray.push(word);
}
});
return finalArray.join(' ');
}
How would you experts suggest writing this? I'm sure I'm not being too efficient at writing this code.
Thank you!
Here's what it looks like inside codewars!
I'd use a regular expression to match 5 or more word characters (\w{5,}), and have a replacer function (String.replace()) return the reversed (reverse()) word:
const spinWords = phrase => phrase.replace(
/\w{5,}/g,
word => [...word].reverse().join('')
);
console.log(spinWords('foo barbar more words go here'));
\w matches a word character - something from A to Z, case-insensitive, or a digit, or an underscore.
The brackets indicates the number of times to repeat the previous token. {5,} starts with a 5 (so, "at least 5") and has nothing after the comma ("up to any number").
Then /g, the global flag, matches and replaces every substring that matches this pattern, not just the first.
The callback function runs for every matched substring, where the argument is the matched substring, and what is returned gets replaced at that point in the original string.
I'm working on a lab assignment for a web applications class and am stuck on implementing a word counter for a basic HTML webpage. The setup of the tests and HTML are already done for us. I simply need to write a function called countWords that takes a string and returns the number of words. It works differently from your traditional word counter though. A word is defined as anything A-Z. Everything else is considered not part of a word. So, if the string is just "234##$^" then the word count is 0. So, I'm not just counting white space like most word counters. All the answers I've found on StackOverflow to similar questions try to just count white space and don't work for my situation. Hence why I made a new question.
My idea was to have a return statement that matches any grouping of a-z using a regular expression and return the length. Then, have a conditional to check for the empty string or string with no letters a-z.
function countWords(s) {
if(s === "" || s === "%$#^23#") {
return 0
}
return s.match(/[^a-z]/gi).length
}
Right now the if statement is just matching the two test cases so that I can pass my tests. I'm not sure how to go about writing another match regular expression to check for no letters in the string or the empty string. Any help is appreciated! Been stuck for a while.
const str1 = '%$#^23#';
const str2 = 'String with ___ special characters and #$&# white spaces !!!';
const str3 = 'Special &$%# characters --> and %$#^5# connected,words but our <++##||++> function,still_works!';
const wordCount = (str) => str.replace(/[\W_\d]/g,' ').split(' ').filter(Boolean).length;
console.log(wordCount(str1)); // 0
console.log(wordCount(str2)); // 7
console.log(wordCount(str3)); // 11
use "regex" to replace all special characters, underscores, numbers, and extra white spaces with an empty space
--> replace(/[\W_\d]/g,' ')
convert the string into an array
--> .split(' ')
use filter to remove all empty string(s) in the array
--> .filter(Boolean)
then, get the word count with "length"
--> .length
You first need to filter the string, remove all the special characters and numbers:
var filtered_test = my_text.replace(/[^a-zA-Z ]/g, '');
then do a normal split and count:
var words = filtered_test.split(" ");
console.log(words.length); //prints out the count of words
You can use a functional replace method to chunk all of the "words" into an array, then simply return the array length. This has the added benefit of providing a 0 count:
explanatory version:
function countWords(str, words = []) {
str.replace(/[A-Z]+/gi, (m) => words.push(m));
return words.length;
}
minimal version:
let countWords = (str, words = []) =>
( str.replace(/[A-Z]+/gi, (m) => words.push(m)), words.length );
let countWords = (str, words = []) => (str.replace(/[A-Z]+/gi, (m) => words.push(m)), words.length);
console.log( "##asdfadf###asfadf: " + countWords("##asdfadf###asfadf") )
console.log("##13424#$#$#$%: " + countWords("##13424#$#$#$%"));
How about this regular expression: /.*?[a-z]+.*?(\s|$)/gi
Use return s.match(/.*?[a-z]+.*?(\s|$)/gi).length
Anything with at least 1 letter in it is counted. Then the phrase O##ne two $#!+ ##%Three four^&&$ five would count as 5 words.
Edit: If you want to be evil to pass your test cases when there are 0 matches use (input.match(/.*?[a-z]+.*?(\s|$)/gi) || "").length
I'm learning how to capitalize the first letter of each word in a string and for this solution I understand everything except the word.substr(1) portion. I see that it's adding the broken string but how does the (1) work?
function toUpper(str) {
return str
.toLowerCase()
.split(' ')
.map(function(word) {
return word[0].toUpperCase() + word.substr(1);
})
.join(' ');
}
console.log(toUpper("hello friend"))
The return value contain 2 parts:
return word[0].toUpperCase() + word.substr(1);
1) word[0].toUpperCase(): It's the first capital letter
2) word.substr(1) the whole remain word except the first letter which has been capitalized. This is document for how substr works.
Refer below result if you want to debug:
function toUpper(str) {
return str
.toLowerCase()
.split(' ')
.map(function(word) {
console.log("First capital letter: "+word[0]);
console.log("remain letters: "+ word.substr(1));
return word[0].toUpperCase() + word.substr(1);
})
.join(' ');
}
console.log(toUpper("hello friend"))
Or you could save a lot of time and use Lodash
Look at
https://lodash.com/docs/4.17.4#startCase -added/edited-
https://lodash.com/docs/4.17.4#capitalize
Ex.
-added/edited-
You may what to use startCase, another function for capitalizing first letter of each word.
_.startCase('foo bar');
// => 'Foo Bar'
and capitalize for only the first letter on the sentence
_.capitalize('FRED');
// => 'Fred'
Lodash is a beautiful js library made to save you a lot of time.
There you will find a lot of time saver functions for strings, numbers, arrays, collections, etc.
Also you can use it on client or server (nodejs) side, use bower or node, cdn or include it manually.
Here is a quick code snippet. This code snippet will allow you to capitalize the first letter of a string using JavaScript.
function capitlizeText(word)
{
return word.charAt(0).toUpperCase() + word.slice(1);
}
The regexp /\b\w/ matches a word boundary followed by a word character. You can use this with the replace() string method to match then replace such characters (without the g (global) regexp flag only the first matching char is replaced):
> 'hello my name is ...'.replace(/\b\w/, (c) => c.toUpperCase());
'Hello my name is ...'
> 'hello my name is ...'.replace(/\b\w/g, (c) => c.toUpperCase());
'Hello My Name Is ...'
function titleCase(str) {
return str.toLowerCase().split(' ').map(x=>x[0].toUpperCase()+x.slice(1)).join(' ');
}
titleCase("I'm a little tea pot");
titleCase("sHoRt AnD sToUt");
The major part of the answers explains to you how works the substr(1). I give to you a better aproach to resolve your problem
function capitalizeFirstLetters(str){
return str.toLowerCase().replace(/^\w|\s\w/g, function (letter) {
return letter.toUpperCase();
})
}
Explanation:
- First convert the entire string to lower case
- Second check the first letter of the entire string and check the first letter that have a space character before and replaces it applying .toUpperCase() method.
Check this example:
function capitalizeFirstLetters(str){
return str.toLowerCase().replace(/^\w|\s\w/g, function (letter) {
return letter.toUpperCase();
})
}
console.log(capitalizeFirstLetters("a lOt of words separated even much spaces "))
Consider an arrow function with an implicit return:
word => `${word.charAt(0).toUpperCase()}${word.slice(1).toLowerCase()}`
This will do it in one line.
Using ES6
let captalizeWord = text => text.toLowerCase().split(' ').map( (i, j) => i.charAt(0).toUpperCase()+i.slice(1)).join(' ')
captalizeWord('cool and cool')
substr is a function that returns (from the linked MDN) a new string containing the extracted section of the given string (starting from the second character in your function). There is a comment on the polyfill implementation as well, which adds Get the substring of a string.
function titlecase(str){
let titlecasesentence = str.split(' ');
titlecasesentence = titlecasesentence.map((word)=>{
const firstletter = word.charAt(0).toUpperCase();
word = firstletter.concat(word.slice(1,word.length));
return word;
});
titlecasesentence = titlecasesentence.join(' ');
return titlecasesentence;
}
titlecase('this is how to capitalize the first letter of a word');
const capitalize = str => {
if (typeof str !== 'string') {
throw new Error('Invalid input: input must of type "string"');
}
return str
.trim()
.replace(/ {1,}/g, ' ')
.toLowerCase()
.split(' ')
.map(word => word[0].toUpperCase() + word.slice(1))
.join(' ');
};
sanitize the input string with trim() to remove whitespace from the leading and trailing ends
replace any extra spaces in the middle with a RegExp
normalize and convert it all toLowerCase() letters
convert the string to an array split on spaces
map that array into an array of capitalized words
join(' ') the array with spaces and return the newly capitalized string
Whole sentence will be capitalize only by one line
"my name is John".split(/ /g).map(val => val[0].toUpperCase() + val.slice(1)).join(' ')
Output "My Name Is John"
A nice simple solution, using pure JavaScript. JSFiddle
function initCap(s) {
var result = '';
if ((typeof (s) === 'undefined') || (s == null)) {
return result;
}
s = s.toLowerCase();
var words = s.split(' ');
for (var i = 0; i < words.length; ++i) {
result += (i > 0 ? ' ' : '') +
words[i].substring(0, 1).toUpperCase() +
words[i].substring(1);
}
return result;
}
Here is an example of how substr works: When you pass in a number, it takes a portion of the string based on the index you provided:
console.log('Testing string'.substr(0)); // Nothing different
console.log('Testing string'.substr(1)); // Starts from index 1 (position 2)
console.log('Testing string'.substr(2));
So, they are taking the first letter of each word, capitalizing it, and then adding on the remaining of the word. Ance since you are only capitalizing the first letter, the index to start from is always 1.
In word.substr(i), the param means the index of the word. This method cuts the word from the letter whose index equals i to the end of the word.
You can also add another param like word.substr(i, len), where len means the length of the character segmentation. For example:
'abcde'.substr(1, 2) → bc.
function toTitleCase(str)
{
return str.replace(/\w\S*/g, function(txt){return
txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
}
Just map through if an array set the first letter as uppercase and concatenate with other letters from index 1.
The array isn't your case here.
const capitalizeNames = (arr) => {
arr.map((name) => {
let upper = name[0].toUpperCase() + name.substr(1)
console.log(upper)
})
}
Here's another clean way of Capitalizing sentences/names/... :
const capitalizeNames =(name)=>{
const names = name.split(' ') // ['kouhadi','aboubakr',essaaddik']
const newCapName = [] // declaring an empty array
for (const n of names){
newCapName.push(n.replace(n[0], n[0].toUpperCase()));
}
return newCapName.join(' ')
}
capitalizeNames('kouhadi aboubakr essaaddik'); // 'Kouhadi Aboubakr Essaaddik'
You could use these lines of code:
function toUpper(str) {
return [str.split('')[0].toUpperCase(), str.split('').slice(1, str.split('').length).join("")].join("")
}
Basically it will split all characters, slice it, create a new array without the first entry/character and replace the first entry/character with an uppercase verion of the character.
(Yes, this was tested and it works on Edge, Chrome and newer versions of Internet Explorer.)
This is probably not the greatest answer, but hopefully it works well enough for you.
I have regexp that extracts values between parentheses.
It's working most of the time but not when it ends with a parentheses
var val = 'STR("ABC(t)")';
var regExp = /\(([^)]+)\)/;.
var matches = regExp.exec(val);
console.log(matches[1]); //"ABC(t"
What I want is "ABC(t)".
Any ideas how I can modify my regexp to Achive this?
Update
The value is always inside the parentheses.
Some examples:
'ASD("123")'; => '123'
'ASD(123)'; => '123'
'ASD(aa(10)asda(459))'; => 'aa(10)asda(459)'
So first there is some text (always text). Then there is a (, and it always ends with a ). I want the value between.
You may use greedy dot matching inside Group 1 pattern: /\((.+)\)/. It will match the first (, then any 1+ chars other than linebreak symbols and then the last ) in the line.
var vals = ['STR("ABC(t)")', 'ASD("123")', 'ASD(123)', 'ASD(aa(10)asda(459))'];
var regExp = /\((.+)\)/;
for (var val of vals) {
var matches = regExp.exec(val);
console.log(val, "=>", matches[1]);
}
Answering the comment: If the texts to extract must be inside nested balanced parentheses, either a small parsing code, or XRegExp#matchRecursive can help. Since there are lots of parsing codes around on SO, I will provide XRegExp example:
var str = 'some text (num(10a ) ss) STR("ABC(t)")';
var res = XRegExp.matchRecursive(str, '\\(', '\\)', 'g');
console.log(res);
<script src="https://cdnjs.cloudflare.com/ajax/libs/xregexp/2.0.0/xregexp-all-min.js"></script>