Every string has empty strings before and after each and every character.
Now, you are doing greedy matching with .*
, which actually means "zero or more characters and match as much as possible". Here, Hello World!
is matched by .*
and then there is global modifier. So, it tries to match again and matches the empty string at the end (which matches because .*
means zero or more characters). That is why you are getting it in the result.
You can confirm the same, with +
, like this
var str = "Hello World!";
var reg = new RegExp(".+", "g");
console.log(str.match(reg));
// [ 'Hello World!' ]
Here, +
means, one or more times. Since the .+
matches Hello World!
, the global modifier searches again but found no more characters to match.
Want to see something interesting? Try this
var str = "Hello World!";
var reg = new RegExp(".*?", "g");
console.log(str.match(reg));
// [ '', '', '', '', '', '', '', '', '', '', '', '', '' ]
Why is that? .*?
means match zero or more characters but match only as minimum as possible (non-greedy). So, it starts from the first character, finds an empty string closes the search. Global modifier makes the match again, finds another empty string after H
, and so on, till the end of the string is reached.
But if you used +
, like this
var str = "Hello World!";
var reg = new RegExp(".+?", "g");
console.log(str.match(reg));
// [ 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!' ]
It has to match one or more characters but match as minimum as possible. So, it matches one characters, stops. Global modifier matches again, matches the second character and so on.