MyString = "big BANANA: 5, pineapple(7), small Apples_juice (1,5%)_, oranges* juice 20 %, , other fruit : no number "
I'd like to get the number of each element in my MyString.
The separator for decimal can be a comma or a dot.
The code I've tried:
function getValue(string, word) {
var index = string.toLowerCase().indexOf(word.toLowerCase()),
part = string.slice(index + word.length, string.indexOf(',', index));
return index === -1 ? 'no ' + word + ' found!' // or throw an exception
: part.replace(/[^0-9$.,]/g, '');
}
If I am not mistaken, looking at your example string you want to get numbers from parts that can be splitted by a comma and a whitespace ,.
If that is the case, then this might be an option:
Create an array using split and loop the items
Check if the word you are looking for in present in the item using indexOf
Use a pattern like \d+(?:[.,]\d+)? for the match
If you have a match, return it.
For example:
var MyString = "big BANANA: 5, pineapple(7), small Apples_juice (1,5%)_, oranges* juice 20 %, , other fruit : no number ";
function getValue(string, word) {
var items = string.toLowerCase().split(', ');
word = word.toLowerCase();
var pattern = /\d+(?:[.,]\d+)?/g;
var result = 'no ' + word + ' found!';
for (var i = 0; i < items.length; i++) {
var item = items[i];
if (item.indexOf(word) !== -1) {
var match = item.match(pattern);
if (match && typeof match[0] !== 'undefined') {
result = match[0];
}
}
}
return result;
}
console.log(getValue(MyString, "big BANANA"));
console.log(getValue(MyString, "pineapple"));
console.log(getValue(MyString, "small Apples_juice"));
console.log(getValue(MyString, "oranges* juice"));
console.log(getValue(MyString, "other fruit"));
console.log(getValue(MyString, "ApPle"));
I recommend rewriting your code to put your values in an object:
var myObj = {
bigBanana: 5,
pineapple: 7,
smallApplesJuice: 1.5,
...
}
You can then iterate through myObj values with a simple for...in loop.
If this is not feasible, you'll have to create different code using RegEx for every substring you want to get our of your big string. For example, try this to get the value of Apples_juice:
//create a regular expression that matches everything after "Apples_juice":
var re = new RegExp(/((?<=Apples_juice).*$)/);
//extract three characters that follow "Apples_juice (":
var extracted_value = MyString.match(re)[0].substring(2,5);
Note that extracted_value is a string, which you will then have to convert to a number. Hope this helps.
Related
I got a string
For example:
This is for trails and I want to learn Js and Coding and Development
The above mentioned line as a string
function trail(sen){
var cat = "and"
var fin = sen.indexOf(cat);
if(fin > 0){
var last = sen.substring(0, fin)
}
else{
var last = sen;
}
return last;
}
console.log(
trail("This is for trails and I want to learn Js and Coding and Development ")
);
I am trying to find the index of the second "and" in a string rather than the first one.
and get the string part from index 0 to that second "and"
Could you please provide the better approach ?
You can use split together with join to achieve this, like so:
const myStr = 'This is for trails and I want to learn Js and Coding and Development'
const subStr = 'and'
const splitted = getSplitted(myStr, subStr, 2) // Splits before the "N th" ocurrence of subStr
console.log(splitted)
function getSplitted(str, subStr, idx) {
return str.split(subStr, idx).join(subStr);
}
You can first find the second occurrence and then remove it via simple slice.
This method also supports regular expressions as pattern.
/**
* Find the n-th occurrence of given pattern in a string.
* #param { string } str The string to be examined.
* #param { string | RegExp } pattern The pattern to be matched.
* #param { number } n Starting index.
* #return { [number, string | RegExpExecArray] } The index & the match result. `[-1, null]` if pattern occurs less than n times.
*/
function findNth(str, pattern, n = 1) {
// The total processed index & and the last match
let index = 0, result;
for(; n--; ) {
// Index of the next match relative to the end of the last one
let offset = -1;
if(pattern instanceof RegExp) {
const match = pattern.exec(str);
if(match !== null) {
offset = match.index;
result = match[0];
}
}
else { // string case
offset = str.indexOf(pattern);
result = pattern;
}
// If none is matched
if(offset === -1)
return [-1, null];
// Seek over the match result
offset += result.length;
str = str.slice(offset);
index += offset;
}
// Gotta go back to the start of the last match
index -= result.length;
return [index, result];
}
/** Remove the n-th occurrence of given pattern out of a string. */
function removeNth(str, pattern, n = 1) {
const result = findNth(str, pattern, n);
if(result[0] === -1)
return str;
return str.slice(0, result[0]) + str.slice(result[0] + result[1].length);
}
{
const str = 'This is for trails and I want to learn Js and Coding and Development';
console.log(removeNth(str, 'and', 2));
console.log(removeNth(str, /\s*and/, 2));
}
Use split
sen.split(cat, 2) // This line will divide the syntax into an array of two elements till second "and" occurrence
// ['This is for trails ', ' I want to learn Js ']
Then you need to join them to add the first and
sen.split(cat, 2).join(cat)
And to get the length
sen.split(cat, 2).join(cat).length
let str = "This is for trails and I want to learn Js and Coding and Development".split("and", 2).join("");
console.log(str);
Sorry if the title sounds confusing. Basically what I am trying to do is to split a decimal number like this 0.1000 into two part - 1. 0.1 and 000 so I can render them differently with different styles.
Check out this screenshot
All the numbers are represented in strings. The tricky part is that we cannot split the number using number.split('0') since we only want to split at the first zero that appears after a non-zero integer.
Not sure how I can do this.
If I did not misunderstand what you are trying to achieve, you can do it with a regex that only matches unlimited zeros that are at the end of the given string like follows:
function markNumber(num) {
return num.replace( /(0{1,})$/g, '<span>$1</span>')
}
const number = 1.2345670089
let renderStyle1 = ''
let renderStyle2 = ''
const string = String(number) + '.'
const parts = string.split('.')
const decimals = parts[1]
const decimalsArray = Array.from(decimals);
// From MDN: The findIndex() method returns the index of the first element in the array that satisfies the provided testing function. Otherwise -1 is returned.
const firstIndexOfZero = decimalsArray.findIndex(x => x === '0');
// From MDN: The slice() method returns a shallow copy of a portion of an array into a new array object selected from start to end (end not included) where start and end represent the index of items in that array. The original array will not be modified.
if(firstIndexOfZero === -1){
renderStyle1 = parts[0] + parts[1]
} else {
renderStyle1 = parts[0] + decimalsArray.slice(0, firstIndexOfZero).join('') // using .join method to convert array to string without commas
renderStyle2 = decimalsArray.slice(firstIndexOfZero, decimalsArray.length).join('') // using .join method to convert array to string without commas
}
console.log(renderStyle1) // "1234567"
console.log(renderStyle2) // "0089"
Messy, and, probably, can be improved, but this should work:
let re = /(\d*\.[1-9]*?)(0.*)/;
["1000", "1.01", "1.10", "1.000", "1.34043"].map((str) =>
str.split(re).filter((entry) => entry !== "")
);
Here's my regex function
const number = ['0.1000', '2.534300', '1.2000', '1.004334000'];
function split_float(num) {
const reg = /^(\d*\.\d*[^0])(0*)$/g;
const [, ...matches] = [...num.matchAll(reg)][0];
return matches;
}
console.log(number.map(split_float));
here is my answer. It uses split and substring to achieve what you want. Tried it in w3school's tryit editor. Handles all of your data in screenshot pretty well:
function myFunction() {
var str = "0.01200";
var partone = str.split(".")[0];
var temp = str.split(".")[1];
for (var i=0; i<temp.length; i++){
if (temp[i] != 0 && temp[i+1] == 0){
break;
}
}
var parttwo = temp.substring(i+1);
partone = partone + "." + temp.substring(0, i+1);
var res = "partOne = " + partone + " and partTwo = " + parttwo;
document.getElementById("demo").innerHTML = res;
}
Here is the screenshot:
Im trying to replace a character at a specific indexOf to uppercase.
My string is a surname plus the first letter in the last name,
looking like this: "lovisa t".
I check the position with this and it gives me the right place in the string. So the second gives me 8(in this case).
first = texten.indexOf(" ");
second = texten.indexOf(" ", first + 1);
And with this I replace the first letter to uppercase.
var name = texten.substring(0, second);
name=name.replace(/^./, name[0].toUpperCase());
But how do I replace the character at "second" to uppercase?
I tested with
name=name.replace(/.$/, name[second].toUpperCase());
But it did´t work, so any input really appreciated, thanks.
Your error is the second letter isn't in position 8, but 7.
Also this second = texten.indexOf(" ", first + 1); gives -1, not 8, because you do not have a two spaces in your string.
If you know that the string is always in the format surname space oneLetter and you want to capitalize the first letter and the last letter you can simply do this:
var name = 'something s';
name = name[0].toUpperCase() + name.substring(1, name.length - 1) + name[name.length -1].toUpperCase();
console.log(name)
Here's a version that does exactly what your question title asks for: It uppercases a specific index in a string.
function upperCaseAt(str, i) {
return str.substr(0, i) + str.charAt(i).toUpperCase() + str.substr(i + 1);
}
var str = 'lovisa t';
var i = str.indexOf(' ');
console.log(upperCaseAt(str, i + 1));
However, if you want to look for specific patterns in the string, you don't need to deal with indices.
var str = 'lovisa t';
console.log(str.replace(/.$/, function (m0) { return m0.toUpperCase(); }));
This version uses a regex to find the last character in a string and a replacement function to uppercase the match.
var str = 'lovisa t';
console.log(str.replace(/ [a-z]/, function (m0) { return m0.toUpperCase(); }));
This version is similar but instead of looking for the last character, it looks for a space followed by a lowercase letter.
var str = 'lovisa t';
console.log(str.replace(/(?:^|\s)\S/g, function (m0) { return m0.toUpperCase(); }));
Finally, here we're looking for (and uppercasing) all non-space characters that are preceded by the beginning of the string or a space character; i.e. we're uppercasing the start of each (space-separated) word.
All can be done by regex replace.
"lovisa t".replace(/(^|\s)\w/g, s=>s.toUpperCase());
Try this one (if it will be helpfull, better move constants to other place, due performance issues(yes, regexp creation is not fast)):
function normalize(str){
var LOW_DASH = /\_/g;
var NORMAL_TEXT_REGEXP = /([a-z])([A-Z])/g;
if(!str)str = '';
if(str.indexOf('_') > -1) {
str = str.replace(LOW_DASH, ' ');
}
if(str.match(NORMAL_TEXT_REGEXP)) {
str = str.replace(NORMAL_TEXT_REGEXP, '$1 $2');
}
if(str.indexOf(' ') > -1) {
var p = str.split(' ');
var out = '';
for (var i = 0; i < p.length; i++) {
if (!p[i])continue;
out += p[i].charAt(0).toUpperCase() + p[i].substring(1) + (i !== p.length - 1 ? ' ' : '');
}
return out;
} else {
return str.charAt(0).toUpperCase() + str.substring(1);
}
}
console.log(normalize('firstLast'));//First Last
console.log(normalize('first last'));//First Last
console.log(normalize('first_last'));//First Last
This question already has answers here:
Extracting numbers from a string using regular expressions
(4 answers)
Closed 8 years ago.
I just learned about RegExp yesterday. I’m trying to figure something out: currently in a function I'm iterating through a string that's been split into an array to pull out and add up the numbers within it. There are examples like, 7boy20, 10, 2One, Number*1*, 7Yes9, Sir2, and 8pop2 which need to have the digits extracted.
So far, this only works to detect a single digit match:
var regexp = /(\d+)/g;
I've also tried:
var regexp =/(\d+)(\d?)/g;
...but it was to no avail.
UPDATE: This is the code I've been using, and am trying to fix as some have asked:
var str = "7boy20 10 2One Number*1* 7Yes9 Sir2 8pop2";
//var str = "7Yes9", "Sir2";
//var str = "7boy20";
function NumberAddition(str) {
input = str.split(" ");
var finalAddUp = 0;
var finalArr = [];
for(var i = 0; i<=input.length-1; i++) {
var currentItem = input[i];
var regexp = /(\d+)/g;
finalArr.push(currentItem.match(regexp));
var itemToBeCounted = +finalArr[i];
finalAddUp += itemToBeCounted;
}
console.log(finalArr);
return finalAddUp;
//OUTPUT ---> [ [ '7', '20' ], [ '10' ], [ '2' ], [ '1' ], [ '7', '9' ], [ '2' ], [ '8', '2' ] ] (finalArr)
//OUTPUT --->NaN (finalAddUp)
How would I turn that output into numbers I can add up?
Is this what you are looking for ?
This will give you every digit by them selves.
var re = /(\d)/g;
var str = '123asdad235 asd 23:"#&22 efwsg34t\nawefqreg568794';
var m;
while ((m = re.exec(str)) != null) {
if (m.index === re.lastIndex) {
re.lastIndex++;
}
// View your result using the m-variable.
// eg m[0] etc.
}
This will give you the numbers and not just the digits.
var re = /(\d+)/g;
var str = '123asdad235 asd 23:"#&22 efwsg34t\nawefqreg568794';
var m;
while ((m = re.exec(str)) != null) {
if (m.index === re.lastIndex) {
re.lastIndex++;
}
// View your result using the m-variable.
// eg m[0] etc.
}
Using the code from the last example m will be an array of all the numbers that you can SUM up using reduce Tho index 0 will always be the entire matched string, so skip that one...
m.reduce(function(previousValue, currentValue, index, array){
return index === 0 ? 0 : previousValue + currentValue;
});
To extract the numbers from the string, you can use one of these:
str.match(/\d+/g)
str.split(/\D+/)
And then, to sum the array, you can use
arr.reduce(function(a,b){ return +a + +b;}); // ES5
arr.reduce((a,b) => +a + +b); // ES6
Example:
"7boy20".split(/\D+/).reduce((a,b) => +a + +b); // Gives 27
Note that browser support for ES6 arrow functions is currently very small.
If you want a regex to match all digit:
var regDigit = /[^0-9.,]/g;
If you want a regex to match all letter:
var regString = /[^a-zA-Z.,]/g;
If you want to see the full JS code:
var s = ["7boy20", "10", "2One", "Number*1*", "7Yes9", "Sir2", , "8pop2"];
var regDigit = /[^0-9.,]/g;
var regString = /[^a-zA-Z.,]/g;
var extractDigit = s[0].replace(regDigit, '');
var extractString = s[0].replace(regString, '');
console.log("The extracted digit is " + extractDigit);
console.log("The extracted string is " + extractString);
Working Demo
To extract the digits, I would just replace the non-digits with nothing
var myregexp = /\D+/g;
result = subject.replace(myregexp, "");
I have a function that get string, I'm looking for a way to format the 3rd word (which is number, that i want to format it with comma). any idea how to do it?
should be something like that:
function formatNumber(txt){
return txt.replace(3rd-word, formatNumber(3rd-word));
}
Match any word that consists of digits, and format it:
txt = txt.replace(/\b(\d+)\b/g, format);
using a formatting function, for example:
function format(s) {
var r = '';
while (s.length > 3) {
r = ',' + s.substr(s.length - 3) + r;
s = s.substr(0, s.length - 3);
}
return s + r;
}
Demo: http://jsfiddle.net/Guffa/5yA62/
Break it down into parts.
Create a function that transforms your word into the format you want.
Split your sentence into words.
Run that function against the appropriate word.
Put the words back into a sentence.
This does not solve your problem. You would still need to find a way to format the number as you choose, but it solves a similar problem of uppercasing the third word:
var transformNth = function(n, fn) {
return function(arr) {
arr[n] = fn(arr[n]);
return arr;
}
};
var makeWords = function(sentence) {return sentence.split(" ");};
var upperCase = function(word) {return word.toUpperCase();}
var transformSentence = function(sentence) {
// index 2 is the third word
return transformNth(2, upperCase)(makeWords(sentence)).join(" ");
}
transformSentence("I have a function that get string");
//=> "I have A function that get string"
transformSentence("I'm looking for a way to format the 3rd word");
//=> "I'm looking FOR a way to format the 3rd word"
transformSentence("which is number");
//=> "which is NUMBER"
transformSentence("that i want to format it with comma");
//=> "that i WANT to format it with comma"
transformSentence("any idea how to do it?");
//=> "any idea HOW to do it?"
transformSentence("should be something like that");
//=> "should be SOMETHING like that"
It might have problems if your sentences have some more complicated structure than single whitespace separation of words that you want to maintain...
You can get the n-th word from the sentence by splitting it up and executing a replace on the word index as specified.
Here is a demo for the code below: DEMO
var sentence = "Total is 123456789!"
var formatNumber = function(value) {
return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
var replaceWord = function(sentence, pos, formatterFunction) {
var matches = sentence.match(/(\b[^\s]+\b)/g);
if (pos < 0 && pos >= matches.length) {
throw "Index out of bounds: " + pos;
}
var match = matches[pos];
var bounded = new RegExp('\\b' + match + '\\b');
return sentence.replace(bounded, formatterFunction(match));
};
console.log(replaceWord(sentence, 2, formatNumber)); // Total is 123,456,789!