Regex'es weird behavior when doing Regex.exec(testString) [duplicate] - javascript

This question already has answers here:
Regex.prototype.exec returns null on second iteration of the search [duplicate]
(2 answers)
Closed 8 years ago.
May I know why the following weird behavior happening for the below statements?
a = /\d+/gi
outputs `/\d+/gi`
a.exec('test1323')
outputs `["1323"]`
and again running the same statements gives
a.exec('test1323')
null
Even I tried creating regex using new Regex("regex string"), but still no change.
Please see the attachment
It happens in chrome console.

You are creating a regexp with the g flag. When you do that, the exec method remembers the position of the last match and matching starts from the last match. The results are explained below:
> a = /\d+/gi
< /\d+/gi // a.lastIndex is initialized to 0
> a.exec("test1323")
< ["1323"] // match begins at 0, match found at index 4...7, a.lastIndex is now 8
> a.exec("test1323")
< null // match begins at 8, no match found, a.lastIndex is reset to 0
> a.exec("test1323")
< ["1323"] // match begins at 0, match found at index 4...7, a.lastIndex is now 8
A longer dry run of similar problem can be found in this answer.

Related

Javascript slice concatenation [duplicate]

This question already has answers here:
JavaScript slice method?
(6 answers)
Closed 4 years ago.
I need to bump a string down 1 index thus moving index 0 to the back.
For example, turn the string '12345' into '23451'. The code below works but I just don't understand why/how.
How does the return statement remember to add '345' back into string s? Shouldn't it be returning the concatenation '21'?
let s = "12345"
let rotate = (function (){
return s.slice(1) + s.slice(0,1);
})
console.log(rotate(s))
"Shouldn't it be returning the concatenation '21'?"
s.slice(1) does not return an element at index 1, but everything that starts from index 1. So in your case it will stand for 2345 and finally will result in 23451.
The slice takes two arguments. If there is only one argument present, it will return the string FROM the first index (missing everything before that). If there are two arguments present, it will return a string containing the characters between the two indices. For this example, it is the first character (from 0 to 1). Then it just adds these two parts together and returns it.
You can read more about the slice function on Mozilla Docs.

Difference between * and + in regex javascript [duplicate]

This question already has answers here:
Regex plus vs star difference? [duplicate]
(9 answers)
Closed 7 years ago.
Both giving the same result so what is the difference between "*" and "+" symbol.
How would I know which one to use.
var str= "oofo fooloo"
var StarSymbol= str.match(/fo*/g);
var PlusSymbol= str.match(/fo+/g)
console.log(StarSymbol) // ["fo", "foo"]
console.log(PlusSymbol) // ["fo", "foo"]
fiddle
You are asking the same question again. So let me explain.
var str= "oofo fooloo"
var StarSymbol= str.match(/fo*/g);
var PlusSymbol= str.match(/fo+/g)
console.log(StarSymbol) // ["fo", "foo"]
console.log(PlusSymbol) // ["fo", "foo"]
Ya, both gives the same result here(for this input) but fo* would match f alone where fo+ would not. * repeats the previous token zero or more times where + repeat the previous token one or more times. So this expects the previous token to be repeated atleast one time.
Example:
> var str= "f"
undefined
> str.match(/fo*/g);
[ 'f' ]
> str.match(/fo+/g);
null
>
o* search's for zero or more o's
o+ search's for one or more o's
go through tutorials
* means between 0 and infinite amount of times, while + means at least one (cannot be zero amount of times)
To be more verbose, * would be like writing {0,}, while + would be like writing {1,}

Why does this semi-colon cause a incorrect falsey result [duplicate]

This question already has answers here:
Why does a RegExp with global flag give wrong results?
(7 answers)
Closed 7 years ago.
Strange truth test results
filter = /rob/gi
>> /rob/gi
filter.test('hey')
>> false
filter.test('rob')
>> true
true && filter.test('rob');
>> false
true && filter.test('rob') ;
>> true
(true && filter.test('rob'));
>> false
(true && filter.test('rob')) ;
>> true
Reproducible in Firefox and Chrome
That's because .test behaves as .exec() and maintains state (position) between calls
As with exec() (or in combination with it), test() called multiple times on the same global regular expression instance will advance past the previous match.
So for the 'rob' input it matches it. Then on the second call it tries to match whatever left after the first match: it's an empty string, so it fails and rewinds.
To see it in action try to match 'robrobrob' - there will be 3 true followed by false.
References:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test
UPD:
In this particular case it happens because you use the g modified (credits to Barmar)

How to prevent regular expression test toggling when using a variable? [duplicate]

This question already has answers here:
Unexpected Javascript RegExp behavior [duplicate]
(3 answers)
Closed 8 years ago.
I just noticed the following strange behavior (both in browsers and nodejs:
> a = /^\/foo/g
/^\/foo/g
> a.test("/foo")
true
> a.test("/foo")
false
> a.test("/foo")
true
> a.test("/foo")
false
> a.test("/foo")
true
What kind of mad science we have here? How can I prevent this behavior?
I just want to have a regex variable that checks if a string matches the pattern globally.
Documentation pages don't seem to bring some light there... I'd really appreciate a link to documentation references.
Set the lastIndex of your regex to 0 after each test.
a = /^\/foo/g
a.test("/foo"); //true
a.test("/foo"); //false
a.test("/foo"); //true
a.lastIndex = 0; //reset the index to start the next match at beginning
a.test("/foo"); //true

Length regex tests true on null [duplicate]

This question already has answers here:
Is it a bug in Ecmascript - /\S/.test(null) returns true?
(2 answers)
Closed 9 years ago.
I need to verify that an input is between 1 and 512 characters long. I'm using the standard length-check regex of /^.{1,512}$/. When I run
/^.{1,512}$/.test(null)
it returns true. How do I get a length-check regex to fail against null? And why does this test true against null in the first place?
EDIT: Leaving this here since it's more googleable in my case than the earlier question, but per here, the problem is that the regex coerces null into 'null' before testing.
I would test with a regex like this:
var myregexp = /^(?!null).{1,512}$/m;;

Categories

Resources