From my understanding, JavaScript's substring methods takes two parameters: first one is the index from where to start, and the second is the end point (non-index type counting, aka number of chars not 0-starting) which does not include the end-point char. Following this logic, I ran two examples:
This first example bellow worked as expected, I counted 13 chars because the 13th char was the end point and was not going to be included.
// goal was to print "Melbourne is"
alert("Melbourne is great".substring(0,13));
This example however failed. In this example I also stopped my count at the end point because I expected it not to be counted.
//goal was to print "Jan"
alert("January".substring(0,4));
Where is my understanding flawed?
JavaScript's substring methods takes two parameters: first one is the index from where to start, and the second is the end point (non-index type counting, aka number of chars not 0-starting) which does not include the end-point char
You are incorrect in this understanding. You are describing the functonality of .substr(). .substring() uses two indexes.
The reason why you are going crazy is because the function
alert("Melbourne is great".substring(0,13));
//prints Melbourne_is_ not Melbourne_is
Notice the space after
Don't go crazy! :)
Related
I want to use regex to find a repeating pattern but I can't work out how to do it. I want to get all matches where there is a number then a plus symbol then another number, including repeats.
So for example, if the string is "5+2-6+10+3", I want to end up with ["5+2", "6+10+3"]
So far I've got
\d*\+\d*
But that doesn't capture the final "+3" in the example above. I had a few attempts using brackets for capturing groups but I couldn't get the output I wanted.
Any help would be much appreciated!
Solved using the following (thanks The fourth bird):
\d+(?:\+\d+)+
I'm not sure what I'm doing wrong, and I'm happy to admit that javascript isn't my strongest language. I test my regexs in a little .net tester I wrote years ago, and I see no problems there. I know different languages implement regex a little differently, but I don't think that's the issue here.
My app has a textarea where I can paste in data from an industry-specific spreadsheet and I use regexp matchAll() to parse. I am looping through the matchAll-returned iterable with a for/of loop, pretty basic stuff, and noticed that I can't seem to get the first match. So If my spreadsheet has 15 lines of data, my javascript parsing handles lines 2-15 ignoring #1. If I copy any lines in the block and paste them to the start then the new line #1 is ignored and the old #1 which is now #2 gets parsed, always ignoring the first line. So the issue is apparently not the RegExp pattern. I googled and found this passage from developer.mozilla.org:
matchAll only returns the first match if the /g flag is missing
this says to me that if I take out the /g I will only get the first match, but I guess this sentence could also be read to mean
unless the /g flag is missing, matchAll will not return the first match
but that would be ridiculous, right? if I take out the /g then I get the first match, and only the first match. if I use /g I get matches 2-15. Why can't I get 1-15? I copied some of my code from a different app I made a few months ago that doesn't have this issue.
working code:
var patt = /(?<invoiceNumber>INV \d+)\t(?<vendor>[\w .,&-]+)\t(?<vendInvNum>[ ()\w\d\/.-]+)\t(20)?(?<yr>\d{2})[-\/](?<mn>\d{1,2})[-\/](?<dd>\d{1,2})\tInvoice\sUSD\s+(?<invAmt>[\d,.-]+)/g
for (let result of objInp.value.matchAll(patt)){
//loops thru iterable
}
example of data pasted in, finds 3 for 3 matches:
INV 006015 VENDOR 1 1025702 26/08/2019 Invoice USD 580.69
INV 006019 VENDOR 2 STORE/090919 09/09/2019 Invoice USD 38.71
INV 006021 Vendor 3 170241569 10/09/2019 Invoice USD 1,080.64
Code that doesn't pull in first match:
var patt = /\s(?<actID>[\w\d-]+)\t(?<actDesc>[\w\d .,&\(\)-]+)?\t(?<origDur>[\d]+)?\t(?<start>[-\d\w]+)?\t(?<end>[-\d\w]+)?/g
for (let result of objInp.value.matchAll(patt[x])){
//loops through but always misses the first match
}
example of pasted data, finds 2 out of 3 matches:
Activity ID Activity Name Original Duration Start Finish Variance - BL1 Finish Date BL1 Finish Total Float
S600-20-21 Executive Steering Committee 5 06-Jan-20 13-Jan-20 0 13-Jan-20 0
S600-20-31 Steering Committee - Option Selection Meeting 2 13-Jan-20 15-Jan-20 0 15-Jan-20 0
S600-20-019b10 Resource Center of Excellence- Review 20 15-Jan-20 12-Feb-20 0 12-Feb-20 0
I'm in the need to check wether some input is strictly as this one:
PEOPLE-123456 or PERSON-12345376 (it can be any combination of numbers)
The number of numbers following the - doesn't matter. It can be from 0 to N numbers.
I've come up with the following expression:
/(PEOPLE-)|(PERSON-)?=^[0-9]+$/
The problem is, this will work even if the characters after the -are not numbers.
PEOPLE-123131 yields true
PERSON-123242 yields true
PERSON-23123.341 yields true
PEOPLE-.2341231 yields false
What am I doing wrong with it? I don't see any problems with the expression itself, maybe I am to noob to see it.
Try this:
^(PERSON|PEOPLE)-[0-9]{1,}$
This ensures the beginnings starts with exactly wither PERSON or PEOPLE, followed by - and ends with at least one number.
You need to put the grouping parentheses around both alternatives:
/^(PEOPLE|PERSON)-\d+$/
And you shouldn't mark it optional with ?. I have no idea why you put = and ^ after that part.
And if you want to allow decimal points in the number, use [0-9.] instead of \d.
This should work if numbers are optional. Otherwise at least 1 number is required replace * with +.
/^(PEOPLE|PERSON)-\d*$/
I'm not particularly strong with Regular Expressions. Basically, I have the following string:
Showing 1-20 of 748 results.
I want to extract the "748", convert it to a number, and use it for comparisons. As expected, "Showing", "of", and "results" are not expected to change, but the numbers could. I have a couple of solutions in mind. The first is using lookbehinds, but I do not believe JS supports them. The second is doing a more blunt approach, maybe finding all the numbers in the string using match() and taking the element at the third index in the returned array (which should be "748").
Any thoughts on the best way to do this?
I would use the regex:
Showing \d+-\d+ of (\d+) results\.
where \d+ in each case means to match 1 or more digits. The parentheses around the number you wanted to find is called a capture group.
So if the search string was in str, the resulting JavaScript might look like:
var resultsRe = /Showing \d+-\d+ of (\d+) results\./;
var numResults = resultsRe.exec(str);
console.log("There are " + numResults + " results.");
For a simple approach you could do the following:
(\d+)\sresults
All it does is capture the integer directly before the word results.
Using JavaScript, I'm looking to pinpoint text that's inside two other strings WITHOUT including those strings. For example:
input: ONE example TWO
regular expression: (?=ONE).+(?=TWO)
matches: ONE example
I want: example
I'm really surprised that the question mark (which is supposed just include that string in the query but not the result) works on the end of the string, but not on the start.
Ah-ha! I figured it out.
for example, here's how to get text inside parenthesis without the parenthesis
(?<=\().+(?=\))
Here's a nice reference: http://www.regular-expressions.info/lookaround.html
Part of my confusion was javascript's fault. It evidently doesn't support "lookbehinds" natively. I found this workaround though:
http://blog.stevenlevithan.com/archives/mimic-lookbehind-javascript
(I use Python's re module to show the examples -- exactly how to do this depends on your regexp implementation [some don't have groups, for example -- or backreferences])
Use a backwards assertion, not a forward assertion, for the first assertion.
>>> re.search(r"(?<=ONE).+(?=TWO)", "ONE x a b TWO").group()
' x a b '
The problem is that the zero width assertion (?=ONE) matches the text "ONE", but doesn't "consume" it -- i.e. it just checks that it's there, but leaves the string as-is. Then the .+ starts reading text, and does consume it.
Backwards assertions don't look ahead, they look behind, so .+ doesn't get run until whatever is behind it is "ONE".
It is probably better not to bother with these at all, but use groups. Consider:
>>> re.search(r"ONE(.+)TWO", "ONE x a b TWO").group(1)
' x a b '