cuantificadores en expresiones regularesQuantifiers in Regular Expressions

Los cuantificadores especifican cuántas instancias de un carácter, grupo o clase de caracteres deben estar presentes en la entrada para que se encuentre una coincidencia.Quantifiers specify how many instances of a character, group, or character class must be present in the input for a match to be found. En la tabla siguiente se indican los cuantificadores compatibles con .NET.The following table lists the quantifiers supported by .NET.

Cuantificador expansivoGreedy quantifier Cuantificador diferidoLazy quantifier DescripciónDescription
* *? Coincide cero o más veces.Match zero or more times.
+ +? Coincide una o más veces.Match one or more times.
? ?? Coincide cero o una vez.Match zero or one time.
{ n }{ n } { n }?{ n }? Coincide exactamente n veces.Match exactly n times.
{ n ,}{ n ,} { n ,}?{ n ,}? Coincide al menos n veces.Match at least n times.
{ n , m }{ n , m } { n , m }?{ n , m }? Coincide de n a m veces.Match from n to m times.

Las cantidades n y m son constantes de tipo entero.The quantities n and m are integer constants. Normalmente, los cuantificadores son expansivos, ya que hacen que el motor de expresiones regulares busque el mayor número posible de repeticiones de patrones concretos.Ordinarily, quantifiers are greedy; they cause the regular expression engine to match as many occurrences of particular patterns as possible. Si se anexa el carácter ? a un cuantificador se convierte en diferido, ya que hace que el motor de expresiones regulares busque el menor número posible de repeticiones.Appending the ? character to a quantifier makes it lazy; it causes the regular expression engine to match as few occurrences as possible. Para obtener una descripción completa de la diferencia entre los cuantificadores expansivos y diferidos, consulte la sección Cuantificadores expansivos y diferidos más adelante en este tema.For a complete description of the difference between greedy and lazy quantifiers, see the section Greedy and Lazy Quantifiers later in this topic.

Importante

El anidamiento de cuantificadores (por ejemplo, como hace el patrón de expresión regular (a*)*) puede aumentar el número de comparaciones que debe realizar el motor de expresiones regulares, como una función exponencial del número de caracteres de la cadena de entrada.Nesting quantifiers (for example, as the regular expression pattern (a*)* does) can increase the number of comparisons that the regular expression engine must perform, as an exponential function of the number of characters in the input string. Para obtener más información sobre este comportamiento y sus soluciones alternativas, consulte Retroceso.For more information about this behavior and its workarounds, see Backtracking.

Cuantificadores de expresiones regularesRegular Expression Quantifiers

En las secciones siguientes se enumeran los cuantificadores admitidos en expresiones regulares de .NET.The following sections list the quantifiers supported by .NET regular expressions.

Nota

Si los caracteres *, +, ?, { y } se encuentran en un patrón de expresión regular, el motor de expresiones regulares los interpreta como cuantificadores o como parte de construcciones de cuantificador, a menos que se incluyan en una clase de caracteres.If the *, +, ?, {, and } characters are encountered in a regular expression pattern, the regular expression engine interprets them as quantifiers or part of quantifier constructs unless they are included in a character class. Para interpretarlos como caracteres literales fuera de una clase de caracteres, debe anteponerles una barra diagonal inversa para indicar su secuencia de escape.To interpret these as literal characters outside a character class, you must escape them by preceding them with a backslash. Por ejemplo, la cadena \* en un patrón de expresión regular se interpreta como un carácter de asterisco literal ("*").For example, the string \* in a regular expression pattern is interpreted as a literal asterisk ("*") character.

Coincidir cero o más veces: *Match Zero or More Times: *

El cuantificador * coincide con el elemento anterior cero o más veces.The * quantifier matches the preceding element zero or more times. Equivale al cuantificador {0,}.It is equivalent to the {0,} quantifier. * es un cuantificador expansivo cuyo equivalente diferido es *?.* is a greedy quantifier whose lazy equivalent is *?.

En el ejemplo siguiente se muestra esta expresión regular.The following example illustrates this regular expression. De los nueve dígitos de la cadena de entrada, cinco coinciden con el patrón y cuatro (95, 929, 9219 y 9919) no coinciden.Of the nine digits in the input string, five match the pattern and four (95, 929, 9219, and 9919) do not.

string pattern = @"\b91*9*\b";   
string input = "99 95 919 929 9119 9219 999 9919 91119";
foreach (Match match in Regex.Matches(input, pattern))
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index);
     
// The example displays the following output:   
//       '99' found at position 0.
//       '919' found at position 6.
//       '9119' found at position 14.
//       '999' found at position 24.
//       '91119' found at position 33.
Dim pattern As String = "\b91*9*\b"   
Dim input As String = "99 95 919 929 9119 9219 999 9919 91119"
For Each match As Match In Regex.Matches(input, pattern)
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next     
' The example displays the following output:   
'       '99' found at position 0.
'       '919' found at position 6.
'       '9119' found at position 14.
'       '999' found at position 24.
'       '91119' found at position 33.

El patrón de expresión regular se define como se muestra en la tabla siguiente.The regular expression pattern is defined as shown in the following table.

ModeloPattern DescripciónDescription
\b Empieza en un límite de palabras.Start at a word boundary.
91* Coincide con un "9" seguido de cero o más caracteres "1".Match a "9" followed by zero or more "1" characters.
9* Coincide con cero o más caracteres "9".Match zero or more "9" characters.
\b Finaliza en un límite de palabras.End at a word boundary.

Coincidir una o más veces: +Match One or More Times: +

El cuantificador + coincide con el elemento anterior una o más veces.The + quantifier matches the preceding element one or more times. Equivale a {1,}.It is equivalent to {1,}. + es un cuantificador expansivo cuyo equivalente diferido es +?.+ is a greedy quantifier whose lazy equivalent is +?.

Por ejemplo, la expresión regular \ban+\w*?\b intenta coincidir con palabras completas que empiezan por la letra a seguida de una o más instancias de la letra n.For example, the regular expression \ban+\w*?\b tries to match entire words that begin with the letter a followed by one or more instances of the letter n. En el ejemplo siguiente se muestra esta expresión regular.The following example illustrates this regular expression. La expresión regular coincide con las palabras an, annual, announcement y antique, y no coincide con autumn y all.The regular expression matches the words an, annual, announcement, and antique, and correctly fails to match autumn and all.

string pattern = @"\ban+\w*?\b";

string input = "Autumn is a great time for an annual announcement to all antique collectors.";
foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase))
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index);
   
// The example displays the following output:   
//       'an' found at position 27.
//       'annual' found at position 30.
//       'announcement' found at position 37.
//       'antique' found at position 57.      
Dim pattern As String = "\ban+\w*?\b"

Dim input As String = "Autumn is a great time for an annual announcement to all antique collectors."
For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next   
' The example displays the following output:   
'       'an' found at position 27.
'       'annual' found at position 30.
'       'announcement' found at position 37.
'       'antique' found at position 57.      

El patrón de expresión regular se define como se muestra en la tabla siguiente.The regular expression pattern is defined as shown in the following table.

ModeloPattern DescripciónDescription
\b Empieza en un límite de palabras.Start at a word boundary.
an+ Coincide con una "a" seguida de uno o más caracteres "n".Match an "a" followed by one or more "n" characters.
\w*? Coincide con un carácter de palabra cero o más veces, pero el menor número de veces que sea posible.Match a word character zero or more times, but as few times as possible.
\b Finaliza en un límite de palabras.End at a word boundary.

Coincidir cero o una vez: ?Match Zero or One Time: ?

El cuantificador ? coincide con el elemento anterior cero o una vez.The ? quantifier matches the preceding element zero or one time. Equivale a {0,1}.It is equivalent to {0,1}. ? es un cuantificador expansivo cuyo equivalente diferido es ??.? is a greedy quantifier whose lazy equivalent is ??.

Por ejemplo, la expresión regular \ban?\b intenta coincidir con palabras completas que empiezan por la letra a seguida de cero o una instancia de la letra n.For example, the regular expression \ban?\b tries to match entire words that begin with the letter a followed by zero or one instances of the letter n. En otras palabras, intenta coincidir con las palabras a y an.In other words, it tries to match the words a and an. En el ejemplo siguiente se muestra esta expresión regular.The following example illustrates this regular expression.

string pattern = @"\ban?\b";
string input = "An amiable animal with a large snount and an animated nose.";
foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase))
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index);
  
// The example displays the following output:   
//        'An' found at position 0.
//        'a' found at position 23.
//        'an' found at position 42.
Dim pattern As String = "\ban?\b"
Dim input As String = "An amiable animal with a large snount and an animated nose."
For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next  
' The example displays the following output:   
'       'An' found at position 0.
'       'a' found at position 23.
'       'an' found at position 42.

El patrón de expresión regular se define como se muestra en la tabla siguiente.The regular expression pattern is defined as shown in the following table.

ModeloPattern DescripciónDescription
\b Empieza en un límite de palabras.Start at a word boundary.
an? Coincide con una "a" seguida de cero o un carácter "n".Match an "a" followed by zero or one "n" character.
\b Finaliza en un límite de palabras.End at a word boundary.

Coincidir exactamente n veces: {n}Match Exactly n Times: {n}

El cuantificador {n} coincide con el elemento anterior exactamente n veces, donde n es un entero.The {n} quantifier matches the preceding element exactly n times, where n is any integer. {n} es un cuantificador expansivo cuyo equivalente diferido es {n}?.{n} is a greedy quantifier whose lazy equivalent is {n}?.

Por ejemplo, la expresión regular \b\d+\,\d{3}\b intenta coincidir con un límite de palabra seguido de uno o más dígitos decimales, seguidos de tres dígitos decimales, seguidos de un límite de palabra.For example, the regular expression \b\d+\,\d{3}\b tries to match a word boundary followed by one or more decimal digits followed by three decimal digits followed by a word boundary. En el ejemplo siguiente se muestra esta expresión regular.The following example illustrates this regular expression.

string pattern = @"\b\d+\,\d{3}\b";
string input = "Sales totaled 103,524 million in January, " + 
                      "106,971 million in February, but only " + 
                      "943 million in March.";
foreach (Match match in Regex.Matches(input, pattern))
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index);
     
//  The example displays the following output:   
//        '103,524' found at position 14.
//        '106,971' found at position 45.
Dim pattern As String = "\b\d+\,\d{3}\b"
Dim input As String = "Sales totaled 103,524 million in January, " + _
                      "106,971 million in February, but only " + _
                      "943 million in March."
For Each match As Match In Regex.Matches(input, pattern)
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next     
' The example displays the following output:   
'       '103,524' found at position 14.
'       '106,971' found at position 45.

El patrón de expresión regular se define como se muestra en la tabla siguiente.The regular expression pattern is defined as shown in the following table.

ModeloPattern DescripciónDescription
\b Empieza en un límite de palabras.Start at a word boundary.
\d+ Buscar coincidencias con uno o más dígitos decimales.Match one or more decimal digits.
\, Coincide con un carácter de coma.Match a comma character.
\d{3} Coincide con tres dígitos decimales.Match three decimal digits.
\b Finaliza en un límite de palabras.End at a word boundary.

Coincidir al menos n veces: {n,}Match at Least n Times: {n,}

El cuantificador {n,} coincide con el elemento anterior al menos n, donde n es un entero.The {n,} quantifier matches the preceding element at least n times, where n is any integer. {n,} es un cuantificador expansivo cuyo equivalente diferido es {n,}?.{n,} is a greedy quantifier whose lazy equivalent is {n,}?.

Por ejemplo, la expresión regular \b\d{2,}\b\D+ intenta coincidir con un límite de palabra seguido de por lo menos dos dígitos, seguidos de un límite de palabra y de un carácter que no sea un dígito.For example, the regular expression \b\d{2,}\b\D+ tries to match a word boundary followed by at least two digits followed by a word boundary and a non-digit character. En el ejemplo siguiente se muestra esta expresión regular.The following example illustrates this regular expression. La expresión regular no coincide con la frase "7 days" porque solo contiene un dígito decimal, pero coincide correctamente con las frases "10 weeks and 300 years".The regular expression fails to match the phrase "7 days" because it contains just one decimal digit, but it successfully matches the phrases "10 weeks and 300 years".

string pattern = @"\b\d{2,}\b\D+";   
string input = "7 days, 10 weeks, 300 years";
foreach (Match match in Regex.Matches(input, pattern))
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index);
 
//  The example displays the following output:
//        '10 weeks, ' found at position 8.
//        '300 years' found at position 18.
 Dim pattern As String = "\b\d{2,}\b\D+"  
 Dim input As String = "7 days, 10 weeks, 300 years"
For Each match As Match In Regex.Matches(input, pattern)
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next 
' The example displays the following output:
'       '10 weeks, ' found at position 8.
'       '300 years' found at position 18.

El patrón de expresión regular se define como se muestra en la tabla siguiente.The regular expression pattern is defined as shown in the following table.

ModeloPattern DescripciónDescription
\b Empieza en un límite de palabras.Start at a word boundary.
\d{2,} Coincide con al menos dos dígitos decimales.Match at least two decimal digits.
\b Coincide con un límite de palabras.Match a word boundary.
\D+ Coincide con al menos un carácter de dígito no decimal.Match at least one non-decimal digit.

Coincidir de n a m veces: {n,m}Match Between n and m Times: {n,m}

El cuantificador {n,m} coincide con el elemento anterior al menos n veces, pero no más de m veces, donde n y m son enteros.The {n,m} quantifier matches the preceding element at least n times, but no more than m times, where n and m are integers. {n,m} es un cuantificador expansivo cuyo equivalente diferido es {n,m}?.{n,m} is a greedy quantifier whose lazy equivalent is {n,m}?.

En el ejemplo siguiente, la expresión regular (00\s){2,4} intenta coincidir con dos ceros seguidos de un espacio que se repitan de dos a cuatro veces.In the following example, the regular expression (00\s){2,4} tries to match between two and four occurrences of two zero digits followed by a space. Observe que la parte final de la cadena de entrada incluye este patrón cinco veces en lugar del máximo de cuatro.Note that the final portion of the input string includes this pattern five times rather than the maximum of four. Pero solo la parte inicial de esta subcadena (hasta el espacio y el quinto par de ceros) coincide con el patrón de la expresión regular.However, only the initial portion of this substring (up to the space and the fifth pair of zeros) matches the regular expression pattern.

string pattern = @"(00\s){2,4}";
string input = "0x00 FF 00 00 18 17 FF 00 00 00 21 00 00 00 00 00";
foreach (Match match in Regex.Matches(input, pattern))
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index);
 
//  The example displays the following output:
//        '00 00 ' found at position 8.
//        '00 00 00 ' found at position 23.
//        '00 00 00 00 ' found at position 35.
Dim pattern As String = "(00\s){2,4}"
Dim input As String = "0x00 FF 00 00 18 17 FF 00 00 00 21 00 00 00 00 00"
For Each match As Match In Regex.Matches(input, pattern)
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next 
' The example displays the following output:
'       '00 00 ' found at position 8.
'       '00 00 00 ' found at position 23.
'       '00 00 00 00 ' found at position 35.

Coincidir cero o más veces (coincidencia diferida): *?Match Zero or More Times (Lazy Match): *?

El cuantificador *? coincide con el elemento anterior cero o más veces, pero el menor número de veces posible.The *? quantifier matches the preceding element zero or more times, but as few times as possible. Es el equivalente diferido del cuantificador expansivo *.It is the lazy counterpart of the greedy quantifier *.

En el ejemplo siguiente, la expresión regular \b\w*?oo\w*?\b coincide con todas las palabras que contienen la cadena oo.In the following example, the regular expression \b\w*?oo\w*?\b matches all words that contain the string oo.

 string pattern = @"\b\w*?oo\w*?\b";
 string input = "woof root root rob oof woo woe";
 foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase))
    Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index);
  
 //  The example displays the following output:
//        'woof' found at position 0.
//        'root' found at position 5.
//        'root' found at position 10.
//        'oof' found at position 19.
//        'woo' found at position 23.
 Dim pattern As String = "\b\w*?oo\w*?\b"
 Dim input As String = "woof root root rob oof woo woe"
 For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
    Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
 Next 
 ' The example displays the following output:
'       'woof' found at position 0.
'       'root' found at position 5.
'       'root' found at position 10.
'       'oof' found at position 19.
'       'woo' found at position 23.

El patrón de expresión regular se define como se muestra en la tabla siguiente.The regular expression pattern is defined as shown in the following table.

ModeloPattern DescripciónDescription
\b Empieza en un límite de palabras.Start at a word boundary.
\w*? Coincide con cero o más caracteres de palabra, pero con el menor número de caracteres posible.Match zero or more word characters, but as few characters as possible.
oo Coincide con la cadena "oo".Match the string "oo".
\w*? Coincide con cero o más caracteres de palabra, pero con el menor número de caracteres posible.Match zero or more word characters, but as few characters as possible.
\b Finaliza en un límite de palabras.End on a word boundary.

Coincidir una o más veces (coincidencia diferida): +?Match One or More Times (Lazy Match): +?

El cuantificador +? coincide con el elemento anterior una o más veces, pero el menor número de veces posible.The +? quantifier matches the preceding element one or more times, but as few times as possible. Es el equivalente diferido del cuantificador expansivo +.It is the lazy counterpart of the greedy quantifier +.

Por ejemplo, la expresión regular \b\w+?\b coincide con uno o más caracteres separados por límites de palabra.For example, the regular expression \b\w+?\b matches one or more characters separated by word boundaries. En el ejemplo siguiente se muestra esta expresión regular.The following example illustrates this regular expression.

string pattern = @"\b\w+?\b";
string input = "Aa Bb Cc Dd Ee Ff";
foreach (Match match in Regex.Matches(input, pattern))
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index);
 
//  The example displays the following output:
//        'Aa' found at position 0.
//        'Bb' found at position 3.
//        'Cc' found at position 6.
//        'Dd' found at position 9.
//        'Ee' found at position 12.
//        'Ff' found at position 15.
 Dim pattern As String = "\b\w+?\b"
 Dim input As String = "Aa Bb Cc Dd Ee Ff"
For Each match As Match In Regex.Matches(input, pattern)
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next 
' The example displays the following output:
'       'Aa' found at position 0.
'       'Bb' found at position 3.
'       'Cc' found at position 6.
'       'Dd' found at position 9.
'       'Ee' found at position 12.
'       'Ff' found at position 15.

Coincidir cero o una vez (coincidencia diferida): ??Match Zero or One Time (Lazy Match): ??

El cuantificador ?? coincide con el elemento anterior cero o una vez, pero el menor número de veces posible.The ?? quantifier matches the preceding element zero or one time, but as few times as possible. Es el equivalente diferido del cuantificador expansivo ?.It is the lazy counterpart of the greedy quantifier ?.

Por ejemplo, la expresión regular ^\s*(System.)??Console.Write(Line)??\(?? intenta coincidir con las cadenas "Console.Write" o "Console.WriteLine".For example, the regular expression ^\s*(System.)??Console.Write(Line)??\(?? attempts to match the strings "Console.Write" or "Console.WriteLine". La cadena también puede incluir "System."The string can also include "System." antes de "Console", y puede ir seguida de un paréntesis de apertura.before "Console", and it can be followed by an opening parenthesis. La cadena debe estar al principio de una línea, aunque puede ir precedida de un espacio en blanco.The string must be at the beginning of a line, although it can be preceded by white space. En el ejemplo siguiente se muestra esta expresión regular.The following example illustrates this regular expression.

string pattern = @"^\s*(System.)??Console.Write(Line)??\(??";
string input = "System.Console.WriteLine(\"Hello!\")\n" + 
                      "Console.Write(\"Hello!\")\n" + 
                      "Console.WriteLine(\"Hello!\")\n" + 
                      "Console.ReadLine()\n" + 
                      "   Console.WriteLine";
foreach (Match match in Regex.Matches(input, pattern, 
                                      RegexOptions.IgnorePatternWhitespace | 
                                      RegexOptions.IgnoreCase | 
                                      RegexOptions.Multiline))
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index);
 
//  The example displays the following output:
//        'System.Console.Write' found at position 0.
//        'Console.Write' found at position 36.
//        'Console.Write' found at position 61.
//        '   Console.Write' found at position 110.
Dim pattern As String = "^\s*(System.)??Console.Write(Line)??\(??"
Dim input As String = "System.Console.WriteLine(""Hello!"")" + vbCrLf + _
                      "Console.Write(""Hello!"")" + vbCrLf + _
                      "Console.WriteLine(""Hello!"")" + vbCrLf + _
                      "Console.ReadLine()" + vbCrLf + _
                      "   Console.WriteLine"
For Each match As Match In Regex.Matches(input, pattern, _
                                         RegexOptions.IgnorePatternWhitespace Or RegexOptions.IgnoreCase Or RegexOptions.MultiLine)
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next 
' The example displays the following output:
'       'System.Console.Write' found at position 0.
'       'Console.Write' found at position 36.
'       'Console.Write' found at position 61.
'       '   Console.Write' found at position 110.

El patrón de expresión regular se define como se muestra en la tabla siguiente.The regular expression pattern is defined as shown in the following table.

ModeloPattern DescripciónDescription
^ Coincide con el inicio del flujo de entrada.Match the start of the input stream.
\s* Busca coincidencias con cero o más caracteres de espacio en blanco.Match zero or more white-space characters.
(System.)?? Coincide con cero o una repetición de la cadena "System.".Match zero or one occurrence of the string "System.".
Console.Write Coincide con la cadena "Console.Write".Match the string "Console.Write".
(Line)?? Coincide con cero o una repetición de la cadena "Line".Match zero or one occurrence of the string "Line".
\(?? Coincide con cero o con una repetición del paréntesis de apertura.Match zero or one occurrence of the opening parenthesis.

Coincidir exactamente n veces (coincidencia diferida): {n}?Match Exactly n Times (Lazy Match): {n}?

El cuantificador {n}? coincide con el elemento anterior exactamente n veces, donde n es un entero.The {n}? quantifier matches the preceding element exactly n times, where n is any integer. Es el equivalente diferido del cuantificador expansivo {n}+.It is the lazy counterpart of the greedy quantifier {n}+.

En el ejemplo siguiente, la expresión regular \b(\w{3,}?\.){2}?\w{3,}?\b se usa para identificar la dirección de un sitio web.In the following example, the regular expression \b(\w{3,}?\.){2}?\w{3,}?\b is used to identify a Web site address. Observe que coincide con "www.microsoft.com" y con "msdn.microsoft.com", pero no coincide con "mywebsite" ni con "mycompany.com".Note that it matches "www.microsoft.com" and "msdn.microsoft.com", but does not match "mywebsite" or "mycompany.com".

string pattern = @"\b(\w{3,}?\.){2}?\w{3,}?\b";
string input = "www.microsoft.com msdn.microsoft.com mywebsite mycompany.com";
foreach (Match match in Regex.Matches(input, pattern))
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index);
     
//  The example displays the following output:
//        'www.microsoft.com' found at position 0.
//        'msdn.microsoft.com' found at position 18.
 Dim pattern As String = "\b(\w{3,}?\.){2}?\w{3,}?\b"
 Dim input As String = "www.microsoft.com msdn.microsoft.com mywebsite mycompany.com"
For Each match As Match In Regex.Matches(input, pattern)
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next     
' The example displays the following output:
'       'www.microsoft.com' found at position 0.
'       'msdn.microsoft.com' found at position 18.

El patrón de expresión regular se define como se muestra en la tabla siguiente.The regular expression pattern is defined as shown in the following table.

ModeloPattern DescripciónDescription
\b Empieza en un límite de palabras.Start at a word boundary.
(\w{3,}?\.) Coincide con al menos 3 caracteres de palabra, pero con el menor número de caracteres posible, seguidos de un carácter de punto.Match at least 3 word characters, but as few characters as possible, followed by a dot or period character. Este es el primer grupo de captura.This is the first capturing group.
(\w{3,}?\.){2}? Coincide con el patrón del primer grupo dos veces, pero el menor número de veces posible.Match the pattern in the first group two times, but as few times as possible.
\b Finalizar la búsqueda de coincidencias en un límite de palabras.End the match on a word boundary.

Coincidir al menos n veces (coincidencia diferida): {n,}?Match at Least n Times (Lazy Match): {n,}?

El cuantificador {n,}? coincide con el elemento anterior al menos n veces, donde n es un entero, pero el menor número de veces posible.The {n,}? quantifier matches the preceding element at least n times, where n is any integer, but as few times as possible. Es el equivalente diferido del cuantificador expansivo {n,}.It is the lazy counterpart of the greedy quantifier {n,}.

Vea el ejemplo del cuantificador {n}? en la sección anterior para obtener una ilustración.See the example for the {n}? quantifier in the previous section for an illustration. La expresión regular de ese ejemplo usa el cuantificador {n,} para coincidir con una cadena que tenga al menos tres caracteres seguidos de un punto.The regular expression in that example uses the {n,} quantifier to match a string that has at least three characters followed by a period.

Coincidir de n a m veces (coincidencia diferida): {n,m}?Match Between n and m Times (Lazy Match): {n,m}?

El cuantificador {n,m}? coincide con el elemento anterior de n a m veces, donde n y m son enteros, pero el menor número de veces posible.The {n,m}? quantifier matches the preceding element between n and m times, where n and m are integers, but as few times as possible. Es el equivalente diferido del cuantificador expansivo {n,m}.It is the lazy counterpart of the greedy quantifier {n,m}.

En el ejemplo siguiente, la expresión regular \b[A-Z](\w*\s+){1,10}?[.!?] coincide con las frases que contengan de una a diez palabras.In the following example, the regular expression \b[A-Z](\w*\s+){1,10}?[.!?] matches sentences that contain between one and ten words. Coincidencia con todas las frases de la cadena de entrada, excepto con una frase que contiene 18 palabras.It matches all the sentences in the input string except for one sentence that contains 18 words.

string pattern = @"\b[A-Z](\w*?\s*?){1,10}[.!?]";
string input = "Hi. I am writing a short note. Its purpose is " + 
                      "to test a regular expression that attempts to find " + 
                      "sentences with ten or fewer words. Most sentences " + 
                      "in this note are short.";
foreach (Match match in Regex.Matches(input, pattern))
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index);
 
//  The example displays the following output:
//        'Hi.' found at position 0.
//        'I am writing a short note.' found at position 4.
//        'Most sentences in this note are short.' found at position 132.
Dim pattern As String = "\b[A-Z](\w*\s?){1,10}?[.!?]"
Dim input As String = "Hi. I am writing a short note. Its purpose is " + _
                      "to test a regular expression that attempts to find " + _
                      "sentences with ten or fewer words. Most sentences " + _
                      "in this note are short."
For Each match As Match In Regex.Matches(input, pattern)
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next 
' The example displays the following output:
'       'Hi.' found at position 0.
'       'I am writing a short note.' found at position 4.
'       'Most sentences in this note are short.' found at position 132.

El patrón de expresión regular se define como se muestra en la tabla siguiente.The regular expression pattern is defined as shown in the following table.

ModeloPattern DescripciónDescription
\b Empieza en un límite de palabras.Start at a word boundary.
[A-Z] Coincide con cualquier letra mayúscula de la A a la Z.Match an uppercase character from A to Z.
(\w*\s+) Coincide con cero o más caracteres de palabra, seguidos de uno o más caracteres de espacio en blanco.Match zero or more word characters, followed by one or more white-space characters. Este es el primer grupo de capturas.This is the first capture group.
{1,10}? Coincide con el patrón anterior entre una y diez veces, pero el menor número de veces que sea posible.Match the previous pattern between 1 and 10 times, but as few times as possible.
[.!?] Coincide con cualquiera de los caracteres de puntuación ".", "!" o "?".Match any one of the punctuation characters ".", "!", or "?".

Cuantificadores expansivos y diferidosGreedy and Lazy Quantifiers

Varios cuantificadores tienen dos versiones:A number of the quantifiers have two versions:

  • Una versión expansiva.A greedy version.

    Un cuantificador expansivo intenta coincidir con un elemento tantas veces como sea posible.A greedy quantifier tries to match an element as many times as possible.

  • Una versión no expansiva o diferida.A non-greedy (or lazy) version.

    Un cuantificador no expansivo intenta coincidir con un elemento el menor número de veces que sea posible.A non-greedy quantifier tries to match an element as few times as possible. Para convertir un cuantificador expansivo en un cuantificador diferido con tan solo agregar el signo ?.You can turn a greedy quantifier into a lazy quantifier by simply adding a ?.

Considere una expresión regular simple diseñada para extraer los cuatro últimos dígitos de una cadena de números, como un número de tarjeta de crédito.Consider a simple regular expression that is intended to extract the last four digits from a string of numbers such as a credit card number. La versión de la expresión regular que usa el cuantificador expansivo * es \b.*([0-9]{4})\b.The version of the regular expression that uses the * greedy quantifier is \b.*([0-9]{4})\b. Pero si una cadena contiene dos números, esta expresión regular coincide con los cuatro últimos dígitos del segundo número, como se muestra en el ejemplo siguiente.However, if a string contains two numbers, this regular expression matches the last four digits of the second number only, as the following example shows.

string greedyPattern = @"\b.*([0-9]{4})\b";
string input1 = "1112223333 3992991999";
foreach (Match match in Regex.Matches(input1, greedyPattern))
   Console.WriteLine("Account ending in ******{0}.", match.Groups[1].Value);

// The example displays the following output:
//       Account ending in ******1999.
Dim greedyPattern As String = "\b.*([0-9]{4})\b"
Dim input1 As String = "1112223333 3992991999"
For Each match As Match In Regex.Matches(input1, greedypattern)
   Console.WriteLine("Account ending in ******{0}.", match.Groups(1).Value)
Next
' The example displays the following output:
'       Account ending in ******1999.

La expresión regular no coincide con el primer número porque el cuantificador * intenta coincidir con el elemento anterior tantas veces como sea posible en toda la cadena y, por tanto, encuentra una coincidencia al final de la cadena.The regular expression fails to match the first number because the * quantifier tries to match the previous element as many times as possible in the entire string, and so it finds its match at the end of the string.

Este no es el comportamiento deseado.This is not the desired behavior. En su lugar, puede usar el cuantificador diferido *? para extraer los dígitos de ambos números, tal como se muestra en el ejemplo siguiente.Instead, you can use the *?lazy quantifier to extract digits from both numbers, as the following example shows.

string lazyPattern = @"\b.*?([0-9]{4})\b";
string input2 = "1112223333 3992991999";
foreach (Match match in Regex.Matches(input2, lazyPattern))
   Console.WriteLine("Account ending in ******{0}.", match.Groups[1].Value);

// The example displays the following output:
//       Account ending in ******3333.
//       Account ending in ******1999.
Dim lazyPattern As String = "\b.*?([0-9]{4})\b"
Dim input2 As String = "1112223333 3992991999"
For Each match As Match In Regex.Matches(input2, lazypattern)
   Console.WriteLine("Account ending in ******{0}.", match.Groups(1).Value)
Next     
' The example displays the following output:
'       Account ending in ******3333.
'       Account ending in ******1999.

En la mayoría de los casos, las expresiones regulares con cuantificadores expansivos y diferidos devuelven las mismas coincidencias.In most cases, regular expressions with greedy and lazy quantifiers return the same matches. Suelen devolver resultados diferentes cuando se usan con el metacarácter comodín (.), que coincide con cualquier carácter.They most commonly return different results when they are used with the wildcard (.) metacharacter, which matches any character.

Cuantificadores y coincidencias vacíasQuantifiers and Empty Matches

Los cuantificadores *, + y {n,m} y sus equivalentes diferidos nunca se repiten tras una coincidencia vacía cuando no se ha encontrado el número mínimo de capturas.The quantifiers *, +, and {n,m} and their lazy counterparts never repeat after an empty match when the minimum number of captures has been found. Esta regla impide que los cuantificadores entren en bucles infinitos en coincidencias de subexpresiones vacías cuando el número máximo de posibles capturas de grupo es infinito o cerca de infinito.This rule prevents quantifiers from entering infinite loops on empty subexpression matches when the maximum number of possible group captures is infinite or near infinite.

Por ejemplo, en el código siguiente se muestra el resultado de una llamada al método Regex.Match con el patrón de expresión regular (a?)* que coincide cero o más veces con cero o un carácter "a".For example, the following code shows the result of a call to the Regex.Match method with the regular expression pattern (a?)*, which matches zero or one "a" character zero or more times. Observe que el único grupo de captura realiza una captura de todos los caracteres "a", así como de String.Empty, pero no hay una segunda coincidencia vacía, ya que la primera coincidencia vacía hace que el cuantificador deje de repetirse.Note that the single capturing group captures each "a" as well as String.Empty, but that there is no second empty match, because the first empty match causes the quantifier to stop repeating.

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = "(a?)*";
      string input = "aaabbb";
      Match match = Regex.Match(input, pattern);
      Console.WriteLine("Match: '{0}' at index {1}", 
                        match.Value, match.Index);
      if (match.Groups.Count > 1) {
         GroupCollection groups = match.Groups;
         for (int grpCtr = 1; grpCtr <= groups.Count - 1; grpCtr++) {
            Console.WriteLine("   Group {0}: '{1}' at index {2}", 
                              grpCtr, 
                              groups[grpCtr].Value,
                              groups[grpCtr].Index);
            int captureCtr = 0;
            foreach (Capture capture in groups[grpCtr].Captures) {
               captureCtr++;
               Console.WriteLine("      Capture {0}: '{1}' at index {2}", 
                                 captureCtr, capture.Value, capture.Index);
            }
         } 
      }   
   }
}
// The example displays the following output:
//       Match: 'aaa' at index 0
//          Group 1: '' at index 3
//             Capture 1: 'a' at index 0
//             Capture 2: 'a' at index 1
//             Capture 3: 'a' at index 2
//             Capture 4: '' at index 3
Imports System.Text.RegularExpressions

Module Example
   Public Sub Main()
      Dim pattern As String = "(a?)*"
      Dim input As String = "aaabbb"
      Dim match As Match = Regex.Match(input, pattern)
      Console.WriteLine("Match: '{0}' at index {1}", 
                        match.Value, match.Index)
      If match.Groups.Count > 1 Then
         Dim groups As GroupCollection = match.Groups
         For grpCtr As Integer = 1 To groups.Count - 1
            Console.WriteLine("   Group {0}: '{1}' at index {2}", 
                              grpCtr, 
                              groups(grpCtr).Value,
                              groups(grpCtr).Index)
            Dim captureCtr As Integer = 0
            For Each capture As Capture In groups(grpCtr).Captures
               captureCtr += 1
               Console.WriteLine("      Capture {0}: '{1}' at index {2}", 
                                 captureCtr, capture.Value, capture.Index)
            Next
         Next 
      End If   
   End Sub
End Module
' The example displays the following output:
'       Match: 'aaa' at index 0
'          Group 1: '' at index 3
'             Capture 1: 'a' at index 0
'             Capture 2: 'a' at index 1
'             Capture 3: 'a' at index 2
'             Capture 4: '' at index 3

Para ver la diferencia práctica entre un grupo de captura que define un número mínimo y máximo de capturas y otro que define un número fijo de capturas, tenga en cuenta los patrones de expresiones regulares (a\1|(?(1)\1)){0,2} y (a\1|(?(1)\1)){2}.To see the practical difference between a capturing group that defines a minimum and a maximum number of captures and one that defines a fixed number of captures, consider the regular expression patterns (a\1|(?(1)\1)){0,2} and (a\1|(?(1)\1)){2}. Ambas expresiones regulares constan de un único grupo de captura, que se define como se muestra en la tabla siguiente.Both regular expressions consist of a single capturing group, which is defined as shown in the following table.

ModeloPattern DescripciónDescription
(a\1 Coincide con "a", junto con el valor del primer grupo capturado...Either match "a" along with the value of the first captured group …
|(?(1) o bien, prueba si se ha definido el primer grupo capturado.or test whether the first captured group has been defined. (Tenga en cuenta que la construcción (?(1) no define un grupo de captura).(Note that the (?(1) construct does not define a capturing group.)
\1)) Si el primer grupo capturado existe, coincide con su valor.If the first captured group exists, match its value. Si el grupo no existe, el grupo coincidirá con String.Empty.If the group does not exist, the group will match String.Empty.

La primera expresión regular intenta coincidir con este patrón de cero a dos veces; el segundo, exactamente dos veces.The first regular expression tries to match this pattern between zero and two times; the second, exactly two times. Dado que el primer modelo alcanza el número mínimo de capturas con su primera captura de String.Empty, nunca se repite para intentar coincidir con a\1; el cuantificador {0,2} solo permite las coincidencias vacías en la última iteración.Because the first pattern reaches its minimum number of captures with its first capture of String.Empty, it never repeats to try to match a\1; the {0,2} quantifier allows only empty matches in the last iteration. En cambio, la segunda expresión regular coincide con "a" porque evalúa a\1 una segunda vez. El número mínimo de iteraciones (dos) obliga al motor a repetirse tras una coincidencia vacía.In contrast, the second regular expression does match "a" because it evaluates a\1 a second time; the minimum number of iterations, 2, forces the engine to repeat after an empty match.

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern, input;
       
      pattern = @"(a\1|(?(1)\1)){0,2}";
      input = "aaabbb"; 

      Console.WriteLine("Regex pattern: {0}", pattern);
      Match match = Regex.Match(input, pattern);
      Console.WriteLine("Match: '{0}' at position {1}.", 
                        match.Value, match.Index);
      if (match.Groups.Count > 1) {
         for (int groupCtr = 1; groupCtr <= match.Groups.Count - 1; groupCtr++)
         {
            Group group = match.Groups[groupCtr];         
            Console.WriteLine("   Group: {0}: '{1}' at position {2}.", 
                              groupCtr, group.Value, group.Index);
            int captureCtr = 0;
            foreach (Capture capture in group.Captures) {
               captureCtr++;
               Console.WriteLine("      Capture: {0}: '{1}' at position {2}.", 
                                 captureCtr, capture.Value, capture.Index);
            }   
         }
      }
      Console.WriteLine();

      pattern = @"(a\1|(?(1)\1)){2}";
      Console.WriteLine("Regex pattern: {0}", pattern);
      match = Regex.Match(input, pattern);
         Console.WriteLine("Matched '{0}' at position {1}.", 
                           match.Value, match.Index);
      if (match.Groups.Count > 1) {
         for (int groupCtr = 1; groupCtr <= match.Groups.Count - 1; groupCtr++)
         {
            Group group = match.Groups[groupCtr];         
            Console.WriteLine("   Group: {0}: '{1}' at position {2}.", 
                              groupCtr, group.Value, group.Index);
            int captureCtr = 0;
            foreach (Capture capture in group.Captures) {
               captureCtr++;
               Console.WriteLine("      Capture: {0}: '{1}' at position {2}.", 
                                 captureCtr, capture.Value, capture.Index);
            }   
         }
      }
   }
}
// The example displays the following output:
//       Regex pattern: (a\1|(?(1)\1)){0,2}
//       Match: '' at position 0.
//          Group: 1: '' at position 0.
//             Capture: 1: '' at position 0.
//       
//       Regex pattern: (a\1|(?(1)\1)){2}
//       Matched 'a' at position 0.
//          Group: 1: 'a' at position 0.
//             Capture: 1: '' at position 0.
//             Capture: 2: 'a' at position 0.
Imports System.Text.RegularExpressions

Module Example
   Public Sub Main()
      Dim pattern, input As String
       
      pattern = "(a\1|(?(1)\1)){0,2}"
      input = "aaabbb" 

      Console.WriteLine("Regex pattern: {0}", pattern)
      Dim match As Match = Regex.Match(input, pattern)
      Console.WriteLine("Match: '{0}' at position {1}.", 
                        match.Value, match.Index)
      If match.Groups.Count > 1 Then
         For groupCtr As Integer = 1 To match.Groups.Count - 1
            Dim group As Group = match.Groups(groupCtr)         
            Console.WriteLine("   Group: {0}: '{1}' at position {2}.", 
                              groupCtr, group.Value, group.Index)
            Dim captureCtr As Integer = 0
            For Each capture As Capture In group.Captures
               captureCtr += 1
               Console.WriteLine("      Capture: {0}: '{1}' at position {2}.", 
                                 captureCtr, capture.Value, capture.Index)
            Next   
         Next
      End If
      Console.WriteLine()

      pattern = "(a\1|(?(1)\1)){2}"
      Console.WriteLine("Regex pattern: {0}", pattern)
      match = Regex.Match(input, pattern)
         Console.WriteLine("Matched '{0}' at position {1}.", 
                           match.Value, match.Index)
      If match.Groups.Count > 1 Then
         For groupCtr As Integer = 1 To match.Groups.Count - 1
            Dim group As Group = match.Groups(groupCtr)         
            Console.WriteLine("   Group: {0}: '{1}' at position {2}.", 
                              groupCtr, group.Value, group.Index)
            Dim captureCtr As Integer = 0
            For Each capture As Capture In group.Captures
               captureCtr += 1
               Console.WriteLine("      Capture: {0}: '{1}' at position {2}.", 
                                 captureCtr, capture.Value, capture.Index)
            Next   
         Next
      End If
   End Sub
End Module
' The example displays the following output:
'       Regex pattern: (a\1|(?(1)\1)){0,2}
'       Match: '' at position 0.
'          Group: 1: '' at position 0.
'             Capture: 1: '' at position 0.
'       
'       Regex pattern: (a\1|(?(1)\1)){2}
'       Matched 'a' at position 0.
'          Group: 1: 'a' at position 0.
'             Capture: 1: '' at position 0.
'             Capture: 2: 'a' at position 0.

Vea tambiénSee also