Lets say I've created some code where the user can keep adding numbers to a <ul> and next to each <li> is a delete button which can be used to remove said item off the list. The problem is for it to work each item on the list does not only contain a number it also contains some text. Lets just say:
<li>Bag of potatoes - 25kg</li>
is there any way that I can use .innerText on this list item, to then just extract the number 25 (or whatever number happens to be there) so that I can subtract it from the total.
I have tried the following:
const itemText = item.parentElement.innerText;
const itemWeight = itemText.match(/\d/g) || [];
However in this example it returns 2,5 rather than 25. Is there a simple way I can convert the result 2,5 to 25, or is it possible to do this in a more efficient manner?
Thanks
parseInt() is pretty sweet
JS
const text = item.parentElement.innerText;
var number = parseInt(text.replace(/[^0-9\.]/g, ''), 10);
console.log(number)
parseInt() will process any string as a number and stop when it reaches a non-numeric character.
as #Zsolt mentions in the comments you should add \d+ where the + means matches the previous match (the \d one) one and unlimited time. so you will get all the numbers in the text.
const itemWeight = itemText.match(/\d+/g) || [];
I really encourage you to play around with this website regex101
it is designed to help you understand the regular expression and test them so on...
I hope that solves your problem. Thanks
Related
This question already has answers here:
Regular expression to get a string between two strings in Javascript
(13 answers)
Get Substring between two characters using javascript
(24 answers)
Closed 2 years ago.
I have a text for example like this:
”Ordernumber 123888 Item 10 SCD”
This I load into an array.
What is the fastest way, to get the string between ”Ordernumber” and ”Item” out of this array? In this case the number ”123888”
I just started with js.
In my real project the text has multiple lines.
And out of it I have to get several other information also (sometimes the last strong, mostly between other strings which are always the same...)
In VBA I was able to load all the text into an array and wrote the VBA with find/search etc.
Now I want to transfer my tool to Google Sheets so I just started to learn/use Javascript.
Thanks in advance for your support and feedbacks go my first question in this community 👍
You could use a regex replacement:
var input = "Ordernumber 123888 Item 10 SCD";
var number = input.replace(/\bOrdernumber (\d+) Item\b.*/, "$1");
console.log(number);
Assuming the words are split using spaces, you can split the string and store it into an array.
const str = ”Ordernumber 123888 Item 10 SCD”; const data = str.split(' '); console.log(data[1]);
Now you can get the data by Index.
I think #Tim Biegeleisen using regex is better,
but another approach to achieve this is by getting the start index of "ordernumber" from the string, and then the same for "Item".
And by using String.prototype.substring(), and providing those indexes you can get the text between those words like so:
const str = "Ordernumber 123888 Item 10 SCD"
const res = str.substring(str.indexOf('Ordernumber') + 'Ordernumber'.length, str.indexOf('Item'));
console.log(res);
String.prototype.indexOf()
String.prototype.substring()
You can use .split () to get the string between one word or another, that way, you will also be able to access the properties of the informed quantity also if you want.
But realizing that it is a sales array, I suggest that you do a decapsulation of your object to be able to better manipulate the data and avoid losing them by being all in a single string.
let string = 'Ordernumber 123888 Item 10 SCD';
let result = string.split('Ordernumber').pop().split('Item')[0];
console.log(result);
I don't believe this is a good way of automating things. Searching in strings is prone to errors and is quite difficult to ensure you are extracting what you are really searching for. This is due to word repetitions etc.
However, one possible solution for you example above is using regular expressions. For your example you can use this (I put in purpose your string in an array as you said):
var c = [”Ordernumber 123888 Item 10 SCD”]
yourNumberThatYouWant = c[0].match(/Ordernumber (.*) Item/)[1]
This will work for short strings where you have these words only once. If you will have for instance the word "Item" repeating elsewhere the solution will bring everything between first instance of "Ordernumber" and last instance of "Item".
let's say I have a URL like:
http://randomsite.com/search?book=1234&chapter=567&pages=0177
Where page count is always four digits, but the book or chapter numbers are ambiguous.
What I want to do is, sometimes from a search, random extra junk might be added after a page query, like session= or referrer= or more. But, I want to cut everything off, no matter what it is, after the string "pages=####".
How would I go about doing that? Thank you!
Try using indexOf and substring:
const str = "http://randomsite.com/search?book=1234&chapter=567&pages=0177&randomjunk"
const strippedStr = str.substring(0, str.indexOf("pages=") + "pages=".length + 4) // always four digits
console.log(strippedStr)
This pertains to any language that you think will work. Is there a way to change the look of a text input to replace every second space (space as in when the space bar is hit it makes a space) i need to a way almost like a counter that once it counts 2 spaces then it replaces that 2nd space to a letter or symbol. if someone could help me with this it would be amazing and the purpose is just to change the way the text looks in this way functionality does not matter as long as it reads like normal text. ( if it helps it would be every odd number of spaces gets changed.)
for example i want to be able to copy and paste something in like this> "i went down to the sea to pick up many sticks for my collection"
and have it return something like this
i%went down%to the%sea to%pick up%many sticks%for my%collection
the end goal is for the symbol to be a different color so it stands out from the text so if that would be possible that would be amazing.
I chose javascript, but there are multiple languages that you could choose and there are multiple ways to accomplish this. This is the train of thought that you should use when solving this problem:
Determine the characters that you want to replace
Determine the character that you want to replace it with
Since we don't want to replace every single one, what is the pattern/frequency that you want to replace found occurrences with.
For the 3rd question, you've said that you want to replace every other occurrence, so we need to keep track of the count of occurrences. And replace it when occurrence modulo 2 = 1. This says replace every odd occurrence.
I chose to use regex to find all the spaces in the sentence, have a counter n and increment the counter every time I find a space.
This leaves us with the following code:
const input = "i went down to the sea to pick up many sticks for my collection";
let n = 0;
const output = input.replace(/\s/g, (m, i, og) => {
return (n++ % 2) ? m : '%';
});
// output = "i%went down%to the%sea to%pick up%many sticks%for my%collection"
Also please take a look at String.prototype.replace() so you can learn about using regex, and to learn about what the function does. This will help you learn and solve similar problems by yourself in the future.
you can use a boolean variable to count odd and even spaces and string.prototyoe.replace with a callback function:
var str = 'i went down to the sea to pick up many sticks for my collection';
var odd = true;
str = str.replace(/\s/gi, (spaceChar)=>{
odd = !odd;
return !odd ? spaceChar : '%'; // this is what you wrote (every second)
// return odd ? spaceChar : '%'; // this is what your expected result shows (every second starting with the first occurence)
});
I have the following example url: #/reports/12/expense/11.
I need to get the id just after the reports -> 12. What I am asking here is the most suitable way to do this. I can search for reports in the url and get the content just after that ... but what if in some moment I decide to change the url, I will have to change my algorythm.
What do You think is the best way here. Some code examples will be also very helpfull.
It's hard to write code that is future-proof since it's hard to predict the crazy things we might do in the future!
However, if we assume that the id will always be the string of consecutive digits in the URL then you could simply look for that:
function getReportId(url) {
var match = url.match(/\d+/);
return (match) ? Number(match[0]) : null;
}
getReportId('#/reports/12/expense/11'); // => 12
getReportId('/some/new/url/report/12'); // => 12
You should use a regular expression to find the number inside the string. Passing the regular expression to the string's .match() method will return an array containing the matches based on the regular expression. In this case, the item of the returned array that you're interested in will be at the index of 1, assuming that the number will always be after reports/:
var text = "#/reports/12/expense/11";
var id = text.match(/reports\/(\d+)/);
alert(id[1]);
\d+ here means that you're looking for at least one number followed by zero to an infinite amount of numbers.
var text = "#/reports/12/expense/11";
var id = text.match("#/[a-zA-Z]*/([0-9]*)/[a-zA-Z]*/")
console.log(id[1])
Regex explanation:
#/ matches the characters #/ literally
[a-zA-Z]* - matches a word
/ matches the character / literally
1st Capturing group - ([0-9]*) - this matches a number.
[a-zA-Z]* - matches a word
/ matches the character / literally
Regular expressions can be tricky (add expensive). So usually if you can efficiently do the same thing without them you should. Looking at your URL format you would probably want to put at least a few constraints on it otherwise the problem will be very complex. For instance, you probably want to assume the value will always appear directly after the key so in your sample report=12 and expense=11, but report and expense could be switched (ex. expense/11/report/12) and you would get the same result.
I would just use string split:
var parts = url.split("/");
for(var i = 0; i < parts.length; i++) {
if(parts[i] === "report"){
this.reportValue = parts[i+1];
i+=2;
}
if(parts[i] === "expense"){
this.expenseValue = parts[i+1];
i+=2;
}
}
So this way your key/value parts can appear anywhere in the array
Note: you will also want to check that i+1 is in the range of the parts array. But that would just make this sample code ugly and it is pretty easy to add in. Depending on what values you are expecting (or not expecting) you might also want to check that values are numbers using isNaN
I have been trying to get a whole array to populate the greatest number within it and I am stumbling.
In my HTML code, I have a number input box where a user can enter it and an alert populate once a user clicks on the "button":
<label for="numbers">Enter numbers seperated by a space.</label><input type="text" size="20" id="numbers">
<div id="greatestbutton" class="button">Click here to get the Greatest Number!</div>
<div>The greatest number is in the alert box.<span id="numbers"></span></div>
In my JS Code, I can get it to recognize the parseFloat, only if the non digit is the first character in the input box, for example "i782" will populate NaN in the alert box, but "7i82", will only populate a 7 in the alert box.
Furthermore, I am unable to get it to go past the first space " ". I am thoroughly stumped and I am also confused that if I put the alert to the var (greatest), it just comes back as 0, yet when I put in alert(array) I at least get something that I hve entered. I know I am missing a step somewhere, but I totally lost.
Any help would be greatly appreciated!!! Thanks!!.
var button = document.getElementById("greatestbutton");
button.onclick = function greaterNumber() {
var array = parseFloat(document.getElementById('numbers').value);
var greatest = 0;
for (i = 0; i < array.length; i++){
if (array[i] > greatest){
var greatest = Math.max(array[i])};
}
alert(array);
}
There's a couple things going wrong here.
For starters, what you want to do is find each valid textual representation of a number in the input box. This is a bit trickier than it sounds - do you want to support negative numbers? Decimal places?
Enter the Regular Expression, one of the most useful inventions in the history of programming. Using a regular expression one can, without too much difficulty, extract all the valid numeric sequences from strings like abc-.02dflaxoe042xne+3.14-5 ( -0.2, 042, +3.14, and -5, that is - all of which can be parsed by parseFloat individually.
This regex does the trick:
/[-+]?(\d+(\.\d+)?|\.\d+)/g
It matches an optional leading - or + ( [-+]? ), followed by either
\d+(\.\d+)?: one or more decimal number 0-9 ( \d ) followed optionally by a decimal point ( \. )and one or more decimal numbers
or
a decimal point \. followed by one or more decimal numbers
The first case matches +3.2, -31, -0.0001, 51, or 42 - the second matches .2, -.1, or +.31. That second case is a bit unusual (no decimal numbers before the decimal point ) but since parseFloat could read them I added them in.
Some might argue that there's a simpler way to write this - I do wish I could combine the either/or, but I couldn't figure out a better regex that made sure that at least one numeric character was supplied. Edits welcome.
The parsing trick, trick, as you were approaching, is to parse out all the numeric substrings first, then parse each into a floating point number and compare. You had some of the right ideas, but there were still some things missing.
Math.max() takes one or more numeric arguments, but can't take an array, unfortunately. It would make a lot of sense if it could, but it can't. I didn't try to find a way around this, though there might be one, because I had to parse each of the numeric strings anyway, I just took max() out completely and used the > operator instead.
A general programming point now: when you're looking for the greatest, don't make assumptions like starting the search at 0. In your example, if no numbers are supplied, or all negative numbers, then the greatest number is your starting point of 0 - which the user may not even have inputted. I initialized my greatest to undefined and then handled that case below.
A bit of further help:
var button = document.getElementById("greatestbutton");
button.onclick = function greaterNumber() {
is a long way of using a variable to say
document.getElementById("greatestbutton").onclick = function greaterNumber() {
You'll notice that you have both the output <span> and the <input> field ( which should end with />, by the way) with an id of numbers - you can't refer to two elements with the same ID of course.
Finally, a semantic point ( :-) ): As a believer in the semantic principles of markup, I'll ask you to avoid all-too-common anti-patterns such as <div id="greatestbutton" class="button">. There is already a <button> tag, and users will be told it's a button even if they're on a braille terminal or other such devices - a <div class='button'> loses this semantic meaning regardless of how pretty you make it with CSS. For the same reason, I replaced your <span> with a <kbd> tag ( for "typed input").
Here's what I came up with:
<script type='text/javascript'>
greaterNumber = function () {
var array = document.getElementById('numbers').value.match(/[-+]?(\d+(\.\d+)?|\.\d+)/g)
alert(array)
if (!array || array.length <= 0) return; // no numbers at all!
var greatest = undefined
if (array.type == 'number') // only one number
array = [array] // convert to array for simplicity
for (var i in array) {
array[i] = parseFloat(array[i])
if (greatest == undefined || array[i] > greatest) greatest = array[i]
}
document.getElementById('greatest').innerHTML = greatest;
}
</script>
</head>
<body>
<p>
<label for="numbers">Enter numbers seperated by a space:</label>
<input type="text" size="20" id="numbers" />
</p>
<p>
<button id="greatestbutton" onclick="greaterNumber()">Click here to get the Greatest Number!</button>
</p>
<div>The greatest number is in the alert box: <kbd id="greatest">?</kbd>
</div>
</html>
See a working example here: http://jsfiddle.net/7JN74/10/