Zhao Li
Zhao Li

Reputation: 5686

Regex for Javascript

I'm trying to learn some basic Javascript regex. As starters, I read the documentation and this SO question: How do you access the matched groups in a JavaScript regular expression?

I think I've deciphered most of the expression:

/(?:^|\s)format_(.*?)(?:\s|$)/g

Except this part:

(.*?)

I know that

.*

is to match 0 or more occurrences of any character (except newline or line terminator).

But I can't figure out why the

?

is needed.

I was playing with something similar:

/(?:^|\s)ab(.*?)ab(?:\s|$)/
' ab4545ab '

And things have been behaving the same with or without the

?

in

(.*?)

Any thoughts?

Thanks!

Upvotes: 1

Views: 98

Answers (3)

user1106925
user1106925

Reputation:

It makes the .* non-greedy. This means that the first occurrence of the next valid character sequence in the regex will halt the .*.

Without the ?, the .* will consume until the last occurrence of the next valid character sequence in the regex.

var s = "foo bar boo bar foo";

var greedy = /.*bar/;
var no_greed = /.*?bar/;

greedy.exec(s); // foo bar boo bar

no_greed.exec(s); // foo bar

So the greedy one consumes past the first "bar" to the last "bar".

The non-greedy only goes to the first "bar".

Upvotes: 5

Niet the Dark Absol
Niet the Dark Absol

Reputation: 324610

The ? makes the quantifier ungreedy. Without it, the * will eat up as many characters as possible, which is particularly powerful with .. However, with the ? there, it will eat as few as necessary.

Take this string, for example: "abcccbacba", and match it against /abc(.*)ba/. It will result in capturing ccbac. On the other hand, /abc(.*?)ba/ will capture cc.

Upvotes: 2

Madara's Ghost
Madara's Ghost

Reputation: 174947

The ? after a .+ or .* match will make the match lazy instead of the default greedy. Meaning, it will match as few characters as possible, in contrast to as many.

Example:

"hello".match(/.+/)    //Returns ["hello"]
"hello".match(/.+?/)   //Returns ["h"]

Upvotes: 4

Related Questions