Compartir a través de


Cuantificadores

Actualización: Julio de 2008

Los cuantificadores especifican cuántas instancias del elemento anterior (que puede ser un carácter, un grupo o una clase de caracteres) debe haber en la entrada para que se encuentre una coincidencia.

Cuantificadores en expresiones regulares de .NET Framework

En la tabla siguiente se enumeran los cuantificadores admitidos en las expresiones regulares de .NET Framework. Las cantidades n y m son constantes de tipo entero. En la sección "Cuantificaciones expansivos y no expansivos" que sigue a la tabla, encontrará una descripción de las diferencias que existen entre los dos tipos de cuantificadores.

Cuantificador

Descripción

*

Coincide con el elemento anterior cero o más veces. Es equivalente a {0,}. * es un cuantificador expansivo cuyo equivalente no expansivo es *?.

Por ejemplo, la expresión regular \b91*9*\b intenta encontrar una coincidencia del dígito 9 después de un límite de palabra. 9 puede ir seguido de cero o varias instancias del dígito 1, que, a su vez, puede ir seguido por cero o más instancias del dígito 9. En el siguiente ejemplo se muestra esta expresión regular. De los nueve dígitos de la cadena de entrada, cinco coinciden con el modelo y cuatro, (95, 929, 9129 y 9919) no.

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.
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.

+

Coincide con el elemento anterior una o más veces. Es equivalente a {1,}. + es un cuantificador expansivo cuyo equivalente no expansivo es +?.

Por ejemplo, la expresión regular \ba(n)+\w*?\b intenta encontrar coincidencias de palabras enteras que comienzan con la letra a seguida de una o varias instancias de la letra n. En el siguiente ejemplo se muestra esta expresión regular. La expresión regular coincide con las palabras an, annual, announcement y antique y, como cabía esperar, no coincide con autumn ni con all.

Dim pattern As String = "\ba(n)+\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.
string pattern = @"\ba(n)+\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.

?

Coincide con el elemento anterior cero o una vez. Es equivalente a {0,1}. ? es un cuantificador expansivo cuyo equivalente no expansivo es ??.

Por ejemplo, la expresión regular \ban?\b intenta encontrar coincidencias de palabras enteras que comienzan con la letra a seguida de cero o una instancia de la letra n. En otras palabras, intenta buscar coincidencias con las palabras a y an. En el siguiente ejemplo se muestra esta expresión regular.

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.
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.

{n}

Coincide con el elemento anterior exactamente n veces. {n} es un cuantificador expansivo cuyo equivalente no expansivo es {n}?.

Por ejemplo, la expresión regular \b\d+\,\d{3}\b intenta encontrar coincidencias de un límite de palabra seguido de uno o varios dígitos decimales, que, a su vez, van seguidos por tres dígitos decimales seguidos por un límite de palabra. En el siguiente ejemplo se muestra esta expresión regular.

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.
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.

{n,}

Coincide con el elemento anterior al menos n veces. {n,} es un cuantificador expansivo cuyo equivalente no expansivo es {n}?.

Por ejemplo, la expresión regular \b\d{2,}\b\D+ intenta encontrar coincidencias con un límite de palabra seguido por lo menos de dos dígitos, que, a su vez, van seguidos de un límite de palabra y un carácter no numérico. En el siguiente ejemplo se muestra esta expresión regular. 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 y 300 years.

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.
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.

{n,m}

Coincide con el elemento anterior al menos n veces, pero no más de m veces. {n,m} es un cuantificador expansivo cuyo equivalente no expansivo es {n,m}?.

Por ejemplo, la expresión regular (00\s){2,4} intenta encontrar coincidencias entre dos y cuatro ocurrencias de dos ceros seguidos de un espacio. En el siguiente ejemplo se muestra esta expresión regular. Observe que la parte final de la cadena de entrada incluye este modelo cinco veces en lugar del máximo de cuatro. Sin embargo, la parte inicial de esta subcadena (hasta el espacio y el quinto par de ceros) coincide con el modelo de la expresión regular.

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.
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.

*?

Coincide con el elemento anterior cero o más veces, pero el menor número de veces que sea posible. Se trata de un cuantificador no expansivo, que es el equivalente del cuantificador expansivo *.

Por ejemplo, las expresiones regulares \b\w*?oo\w*?\b coinciden con todas las palabras que contienen oo. En el siguiente ejemplo se muestra esta expresión regular.

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.
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.

+?

Coincide con el elemento anterior una o más veces, pero el menor número de veces que sea posible. Se trata de un cuantificador no expansivo, que es el equivalente del cuantificador expansivo +.

Por ejemplo, la expresión regular \b\w+?\b coincide con uno o varios caracteres separados por límites de palabra. En el siguiente ejemplo se muestra esta expresión regular.

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.
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.

??

Coincide con el elemento anterior cero o una vez, pero el menor número de veces que sea posible. Se trata de un cuantificador no expansivo, que es el equivalente del cuantificador expansivo ?.

Por ejemplo, la expresión regular ^(\s)*(System.)??Console.Write(Line)??\(?? intenta encontrar coincidencias con las cadenas Console.Write o Console.WriteLine. La cadena también puede incluir System. antes que Console y puede ir seguida de un paréntesis de apertura. La cadena debe estar al comienzo de una línea, aunque puede ir precedida de un espacio en blanco. En el siguiente ejemplo se muestra esta expresión regular.

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.
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.

{n}?

Coincide con el elemento anterior exactamente n veces. Se trata de un cuantificador no expansivo, que es el equivalente del cuantificador expansivo {n}+.

Por ejemplo, la expresión regular \b(\w{3,}?\.){2}?\w{3,}?\b coincide exactamente con dos conjuntos de caracteres seguidos de un punto en un límite de palabra. A continuación, le sigue otro conjunto de caracteres y un límite de palabra. Esta expresión regular debería identificar la dirección de un sitio web. En el siguiente ejemplo se muestra la expresión regular. Observe que coincide con www.microsoft.com y mdsn.microsoft.com, pero no coincide con mywebsite ni con mycompany.com.

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.
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.

{n,}?

Coincide con el elemento anterior por lo menos n veces, pero el menor número de veces posible. Se trata de un cuantificador no expansivo, que es el equivalente del cuantificador expansivo {n,}.

Vea el ejemplo del cuantificador {n}? como demostración. La expresión regular de ese ejemplo utiliza el cuantificador {n,} para buscar coincidencias con una cadena que tenga al menos tres caracteres seguidos de un punto.

{n,m}?

Coincide con el elemento anterior entre n y m veces, pero el menor número de veces posible. Se trata de un cuantificador no expansivo, que es el equivalente del cuantificador expansivo {n,m}.

Por ejemplo, la expresión regular \b[A-Z](\w*?\s*?){1,10}[.!?] busca coincidencias con frases que contengan entre una y diez palabras. Coincide con un límite de palabra seguido de una letra mayúscula que, a su vez, va seguida de entre una y diez repeticiones de cero o más caracteres alfabéticos y, opcionalmente, de un carácter de espacio en blanco. La coincidencia, a continuación, finaliza con un punto, un signo de exclamación o un signo de interrogación. En el siguiente ejemplo se muestra esta expresión regular. Coincide con todas las frases de la cadena de entrada a excepción de una única frase, que contiene 18 palabras.

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.
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.

Cuantificadores expansivos y no expansivos

Hay varios cuantificadores que tienen dos versiones:

  • Una versión expansiva.

    Un cuantificador expansivo intenta buscar coincidencias con el elemento al que se aplica tantas veces como sea posible.

  • Una versión no expansiva.

    Un cuantificador no expansivo intenta buscar coincidencias con el elemento al que se aplica el menor número de veces posible.

Para mostrar la diferencia, considere una expresión regular muy simple con la que se pretende extraer los cuatro últimos dígitos de una cadena de números como los de una tarjeta de crédito. La versión de la expresión regular que utiliza el cuantificador * expansivo es \b.*([0-9]{4})\b. Sin embargo, en una cadena que contenga dos números, encontrará coincidencias al mostrar únicamente los cuatro últimos dígitos del segundo número, tal y como se muestra en el ejemplo siguiente.

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.
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.

Éste no es el comportamiento deseado. La expresión regular no coincide con el primer número porque el cuantificador * intenta buscar coincidencias con el elemento anterior tantas veces como sea posible en toda la cadena y, por tanto, encuentra su coincidencia al final de la cadena.

Sin embargo, una expresión regular equivalente que utilice el cuantificador no expansivo *? tendría el comportamiento esperado, tal y como se muestra en el ejemplo siguiente.

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.
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.

En la mayoría de los casos, las expresiones regulares con cuantificadores expansivos y no expansivos devuelven las mismas coincidencias. La mayor parte de las veces, devuelven resultados diferentes cuando se utilizan con un punto (metacarácter .), que coincide con cualquier carácter.

Vea también

Otros recursos

Elementos del lenguaje de expresiones regulares

Historial de cambios

Fecha

Historial

Motivo

Julio de 2008

Revisado exhaustivamente.

Corrección de errores de contenido.