Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

meaning of a `+` following a `*`, when the latter is used as a quantifier in a regular expression

Tags:

regex

ruby

Today I came across the following regular expression and wanted to know what Ruby would do with it:

> "#a" =~ /^[\W].*+$/
=> 0
> "1a" =~ /^[\W].*+$/
=> nil

In this instance, Ruby seems to be ignoring the + character. If that is incorrect, I'm not sure what it is doing with it. I'm guessing it's not being interpreted as a quantifier, since the * is not escaped and is being used as a quantifier. In Perl/Ruby regexes, sometimes when a character (e.g., -) is used in a context in which it cannot be interpreted as a special character, it is treated as a literal. But if that was happening in this case, I would expect the first match to fail, since there is no + in the lvalue string.

Is this a subtly correct use of the + character? Is the above behavior a bug? Am I missing something obvious?

like image 377
Eric Walker Avatar asked Sep 24 '13 00:09

Eric Walker


People also ask

What is quantifiers in regular expression?

quantifier matches the preceding element zero or more times but as few times as possible. It's the lazy counterpart of the greedy quantifier * . In the following example, the regular expression \b\w*?

How are quantifiers used in regular expressions in Java?

Regular Expression in Java - Quantifiers Java Regex Quantifiers can be used with character classes and capturing groups also. For example, [abc]+ means - a, b, or c - one or more times. (abc)+ means the group “abc” one more more times.

What are quantifiers and sequence character in regular expression in Python?

Special Characters are meta-characters that give special meaning to the syntax of regular expression search. Quantifiers specify “how often” do we match a preceding regular expression. Anchors specify “where” do we match. Anchors allow a user to specify position for text/pattern search.

Which of the following quantifiers matches any string?

The n? quantifier matches any string that contains zero or one occurrences of n.


1 Answers

Well, you can certainly use a + after a *. You can read a bit about it on this site. The + after the * is called a possessive quantifier.

What it does? It prevents * from backtracking.

Ordinarily, when you have something like .*c and using this to match abcde, the .* will first match the whole string (abcde) and since the regex cannot match c after the .*, the engine will go back one character at a time to check if there is a match (this is backtracking).

Once it has backtracked to c, you will get the match abc from abcde.

Now, imagine that the engine has to backtrack a few hundred characters, and if you have nested groups and multiple * (or + or the {m,n} form), you can quickly end up with thousands, millions of characters to backtrack, called catastrophic backtracking.

This is where possessive quantifiers come in handy. They actually prevent any form of backtracking. In the above regex I mentioned, abcde will not be matched by .*+c. Once .*+ has consumed the whole string, it cannot backtrack and since there's no c at the end of the string, the match fails.

So, another possible use of possessive quantifiers is that they can improve the performance of some regexes, provided the engine can support it.

For your regex /^[\W].*+$/, I don't think that there's any improvement (maybe a tiny little improvement) that the possessive quantifier provides though. And last, it might easily be rewritten as /^\W.*+$/.

like image 164
Jerry Avatar answered Oct 05 '22 13:10

Jerry