TOC

This article is currently in the process of being translated into Spanish (~99% done).

Regular Expressions (Regex):

Regex Modifiers

En artículos previos, hablamos de lo que son las Expresiones Regulares y como usarlas en C# para encontrar ocurrencias, reemplazar y otros. En este punto, ya debe haberse dado cuenta de lo poderosas que son las Expresiones Regulares y de como pueden ayudarle en un monton de situaciones, pero aún son más poderosas cuando usted sabe acerca de los modificadores posibles.

Cuando trabaja con Expresiones Regualres, puede usar uno o varios modificadores para controlar el comportamiento de la máquina de búsqueda de coincidencias. Por ejemplo, un proceso de búsqueda Regex es usualmente sensitivo a mayúsculas y minúsculas, significa que "a" es diferente de "A". Sin embargo, en muchas situaciones, usted quiere que sus búsquedas sean insensitivas a minúsculas y maypusculas de tal modo que el caracter "a" sea sólo una letra, no importa si está en minúsculas o en mayúsculas. Simplemente provea la opción RegexOptions.IgnoreCase cuando crea la instancia de Regex y su búsqueda será insensitiva a minúsculas y mayúsculas.

Encontrará todos los modificadores disponibles en la enumeración RegexOptions. Varios de ellos son comunes entre todos los lenguajes de programación soportando el estándar de Expresiones Regulares, mientras que otros son específicos del ambiente .NET.

Como verá en el primer ejemplo, los modificadores de Regex son usualmente especificados como el segundo parámetro cuando crea una instancia de Regex. Puede especificar más de una opción perarada con un caracter de tuberia (|), [en realidad es un operador O por bits] como este:

new Regex("[a-z]+", RegexOptions.IgnoreCase | RegexOptions.Singleline);

Ahora corramos todos los modificadores para darle una idea de como trabajan y que pueden hacer por usted.

RegexOptions.IgnoreCase

Esto probablemente será uno de sus modificadores más usados. Como se describió arriva, cambiará las Expresiones Regulares de ser sensitivas a minúsculas y mayúsculas a ser insensitivas. Esto hace una gran diferencia, como puede ver en este ejemplo:

public void IgnoreCaseModifier()
{
	string testString = "Hello World";
	string regexString = @"^[a-z\s]+$";
	Regex caseSensitiveRegex = new Regex(regexString);
	Regex caseInsensitiveRegex = new Regex(regexString, RegexOptions.IgnoreCase);

	Console.WriteLine("Case-sensitive match: " + caseSensitiveRegex.IsMatch(testString));
	Console.WriteLine("Case-insensitive match: " + caseInsensitiveRegex.IsMatch(testString));
}

Especificamos una Regex simple, diseñada para encontrar sólo las letras (a-z) y espacios en blanco. La usamos para crear dos instancias de Regex: Una sin el modificador RegexOptions.IgnoreCase y otra con el, y luego intentamos encontrar coincidencias en la misma cades de prueba, la cual consiste en caracteres en minúsculas y mayúsculas y un espacio en blanco. La salida, probablemente no sorprendentemente, se verá somo esto:

Case-sensitive match: False
Case-insensitive match: True

RegexOptions.Singleline

En Expresiones Regulares, el punto (.) es básicamente un captura-todo caracter. Sin embargo, por omisión, no corresponde con un fin de línea, lo que significa que usted puede usar el punto para empatar una línea entera de letras, números, caracteres especiales, etc, pero la búsqueda terminará tan pronto como encuentre un fin de línea. Sin embargo, si usted provee un modificador Singleline, el punto empatará con fines de línea también. Permítame demostrar la diferencia:

public void SinglelineModifier()
{
	string testString = 
						@"Hello World
						This string contains
						several lines";
	string regexString = ".*";
	
	Regex normalRegex = new Regex(regexString);
	Regex singlelineRegex = new Regex(regexString, RegexOptions.Singleline);			

	Console.WriteLine("Normal regex: " + normalRegex.Match(testString).Value);
	Console.WriteLine("Singleline regex: " + singlelineRegex.Match(testString).Value);
}

La salida se verá como esto:

Normal regex: Hello World

Singleline regex: Hello World
							This string contains
                            several lines

RegexOptions.Multiline

Como hemos hablado en este capítulo, las Expresiones Regulares consisten en muchos caracteres diferentes los cuales tienen propósitos especiales. Otro ejemplo de esto es estos dos caracteres: ^ y $. En realidad los usamos en el ejemplo sensitivo a mayúsculas arriba, para empatar el inicio y el fin de una cadena. Sin embargo, al proveer el modificador Multiline, puede cambiar este comportamiento de empatar el inicio/fin de una cadena para empatar el inicio/fin de líneas. Esto es muy útil cuando quiere lidiar individualmente con las líneas empatadas. Aquí está un ejemplo:

public void MultilineModifier()
{
	string testString =
						@"Hello World
						This string contains
						several lines";
	string regexString = "^.*$";

	Regex singlelineRegex = new Regex(regexString, RegexOptions.Singleline);
	Regex multilineRegex = new Regex(regexString, RegexOptions.Multiline);

	Console.WriteLine("Singleline regex: " + singlelineRegex.Match(testString).Value);

	Console.WriteLine("Multiline regex:");
	MatchCollection matches = multilineRegex.Matches(testString);
	for(int i = 0; i < matches.Count; i++)
		Console.WriteLine("Line " + i + ": " + matches[i].Value.Trim());
}

Note como uso una cadena de prueba con varias líneas y luego uso los mecanismos de empate diferentemente: Con singlelineRegex, tratamos la cadena de prueba completa como una sola línea, aunque contenga fines de línea, como lo discutimos arriba. Cuando usamos el modificador multilineRegex tratamos a la cadena de prueba como mútiples líneas, cada una resultando en un empate. Usamos el método Regex.Matches() para capturar cada línea y trabajr con ella - en este caso, simplemente las escribimos en la Consola.

RegexOptions.Compiled

Mientras las Expresiones Regulares son generalmente rápidas, pueden alentar las cosas un poco si son muy complejas y ejecutadas muchas veces, por ejemplo en el ciclo. Para estas situaciones, quizá quiera usar el modificador RegexOptions.Compiled, el cual permitirá al ambiente compilar la Regex en un ensamble. Esto cuesta un poco de tiempo extra cuando es creada, comparado con sólo instanciar un objeto Regex normalmente, pero hará todas las operaciones Regex subsecuentes (búsquedas etc.) más rápidas:

Regex compiledRegex = new Regex("[a-z]*", RegexOptions.Compiled);

Más modificadores

Los modificadores de arriba son los más interesantes, pero hay unos poco más, los cuales solamente veremos brevemente:

  • RegexOptions.CultureInvariant: Con este moficador, las diferencias culturales en un lenguaje son ingoradas. Esto es más relevante si sus aplicaciones trabajan con múltiples lenguajes no-Inglés.
  • RegexOptions.ECMAScript: Cambia a la variante Regex usada de la versión específica .NET al estándar ECMAScript. Esto debería ser raramente necesaria.
  • RegexOptions.ExplicitCapture: Normalmente, un conjunto de paréntesis en una Regex actua como un grupo de captura, permitiendole accesar a cada valor capturado a través de un índice. Si especifica el modificador ExplicitCapture, este comportamiento es cambiado de tal modo que sólo grupos nombrados con capturados y almacenados para acceder más tarde.
  • RegexOptions.IgnorePatternWhitespace: Cuando este modificador esta habilitado, los espacios en blanco en la Regex son ignorados y le permite incluso incluir comentarios, con el caracter prefijo hash (#).
  • RegexOptions.RightToLeft: Cambia la búsqueda y ocurrencias para empezar de derecha a izquierda, en vez del comportamiento por omisión de izquierda a derecha.

Resumen

Como puede ver, hay muchos modificadores Regex que debe conocer para tomar ventaja total de las Expresiones Regulares, para soportar tantos casos como sea posible.


This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!