BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

Regular Expressions
.NET 1.1+

Regular Expression Quantifiers

The seventh part of the Regular Expressions in .NET tutorial continues to look at the pattern-matching characters that can be used in regular expressions. This article describes quantifiers, which allow matching repeating items in the source text.

Matching a Specific Number of Repeated Items

When you need more control over the number of repetitions, you can specify exactly how many times a pattern should appear. To do so, follow the repeating part of the pattern with a number contained within braces. For example, to find an item three times you would follow it with "{3}".

The sample code below looks for groups of four adjacent digits. There is only one such match in the input string.

string input = "1234 A123 AB12 ABC1 ABCD";

foreach (Match match in Regex.Matches(input, @"\d{4}"))
{
    Console.WriteLine("Matched '{0}' at index {1}", match.Value, match.Index);
}

/* OUTPUT
    
Matched '1234' at index 0
             
*/

You can use braces to specify the minimum number of repetitions to match for a less restrictive pattern. To do so, add a comma after the number within the braces. For example, "{2,}" matches two or more items.

The updated sample below finds two or more adjacent numeric digits:

string input = "1234 A123 AB12 ABC1 ABCD";

foreach (Match match in Regex.Matches(input, @"\d{2,}"))
{
    Console.WriteLine("Matched '{0}' at index {1}", match.Value, match.Index);
}

/* OUTPUT
    
Matched '1234' at index 0
Matched '123' at index 6
Matched '12' at index 12
             
*/

Finally, you can specify a minimum and maximum number of repetitions within the braces. The minimum appears first and is separated from the maximum by a comma. For example, to find between one and three items you would use, "{1,3}".

The following sample code finds items that contain between one and three capital letters followed by one to three digits:

string input = "1234 A123 AB12 ABC1 ABCD";

foreach (Match match in Regex.Matches(input, "[A-Z]{1,3}[0-9]{1,3}"))
{
    Console.WriteLine("Matched '{0}' at index {1}", match.Value, match.Index);
}

/* OUTPUT
    
Matched 'A123' at index 5
Matched 'AB12' at index 10
Matched 'ABC1' at index 15
             
*/

Greedy and Lazy Quantifiers

Quantifiers can be either greedy or lazy. All of the above examples use greedy quantifiers, which means that they match as many repetitions as possible. For example, matching "\d+" will find a numeric digit and match it and every following character until a non-numeric character, or the end of the text, is encountered.

A lazy quantifier works differently. As soon as enough characters have been found to correspond to the pattern, a match is returned. This means that lazy quantifiers return as few repetitions as possible. Often this means that the source text will return more matches but each will be shorter. To specify that a quantifier should be lazy, you append a question mark (?).

Try running the following code. Here the same input text is matched against two patterns. The first looks for a '2', followed by one or more digits. As the quantifier is greedy, there is a single match that consumes the first '2' and every subsequent digit.

The second pattern is similar to the first but uses a lazy quantifier. As such, there are two matches, each only two characters in length. The matches occur at the index of each '2', matching that number and just one further digit.

string input = "A long number: 0123456789876543210";

foreach (Match match in Regex.Matches(input, @"2\d+"))
{
    Console.WriteLine("Greedy matched '{0}' at index {1}", match.Value, match.Index);
}

Console.WriteLine();

foreach (Match match in Regex.Matches(input, @"2\d+?"))
{
    Console.WriteLine("Lazy matched   '{0}' at index {1}", match.Value, match.Index);
}


/* OUTPUT
    
Greedy matched '23456789876543210' at index 17

Lazy matched   '23' at index 17
Lazy matched   '21' at index 31
             
*/
30 September 2015