0

I have the following regex that determines (I hope) if a string is a URL or not.

/^(((\/[\w-]+)+\/?)|(((http|ftp|https):\/\/)[\w-]+))((\.[\w-]+)?([\w.,@?^=%&amplL\/~+#-]*[\w@?~=%&:\/~+#-])?)$/gi

What I find is that if I save that regex to an object, then test the same string twice, I get two different results as shown in this JSFiddle

https://jsfiddle.net/gpc5trsw/

The code in this fiddle looks like this:

var test = /^(((\/[\w-]+)+\/?)|(((http|ftp|https):\/\/)[\w-]+))((\.[\w-]+)?([\w.,@?^=%&amplL\/~+#-]*[\w@?~=%&:\/~+#-])?)$/gi
var str = "/api/WebTest";

document.getElementById("firstCtr").innerHTML = /^(((\/[\w-]+)+\/?)|(((http|ftp|https):\/\/)[\w-]+))((\.[\w-]+)?([\w.,@?^=%&amplL\/~+#-]*[\w@?~=%&:\/~+#-])?)$/gi.test(str)
document.getElementById("secondCtr").innerHTML = /^(((\/[\w-]+)+\/?)|(((http|ftp|https):\/\/)[\w-]+))((\.[\w-]+)?([\w.,@?^=%&amplL\/~+#-]*[\w@?~=%&:\/~+#-])?)$/gi.test(str)


document.getElementById("first").innerHTML = test.test(str)
document.getElementById("second").innerHTML = test.test(str)

With the following HTML:

<div>
First Run Control: <span id="firstCtr"></span>
</div>
<div>
Second Run Control: <span id="secondCtr"></span>
</div>
<hr/>
<div>
First Run: <span id="first"></span>
</div>
<div>
Second Run: <span id="second"></span>

The resulting HTML output is as such:

First Run Control: true
Second Run Control: true


First Run: true
Second Run: false

Why does the results of the test change the second time it's tested on the object version? JavaScript can be a cruel mistress sometimes...

joe_coolish
  • 7,201
  • 13
  • 64
  • 111

1 Answers1

1

using the /g, the regex object will remember ur last position every call u make. It will work and get the correct result the first time, but in the next call it will start from the point after the first match.

it will be clear if u have 2 matches inside as below example

var test = /\d+/gi
var str = "1234 vvv 3333";
document.getElementById("firstCtr").innerHTML = /\d+/gi.test(str);
document.getElementById("secondCtr").innerHTML = /\d+/gi.test(str);
document.getElementById("first").innerHTML = test.test(str);
document.getElementById("second").innerHTML = test.test(str);

The output result will be

First Run Control: true 
Second Run Control: true 
First Run: true
Second Run: true

if you change the str to "1234 vvvv"

you will get the same as your previous results

 First Run: true 
 Second Run: false
Sufyan Jabr
  • 791
  • 4
  • 20