Empezare presentando algunos conceptos, luego analizaré uno ellos y finalmente mediante una aplicación en C# aplicare las expresiones regulares desde lo más simple a algo más complejo.
Nota
Es importante ejecutar o construir el código para ir avanzado de lo más simple a lo complejo y notar como el motor de C# hace uso de las expresiones regulares. He usado el libro, "Introducing Regular Expressions", Editorial O'REILLY, Michael Fitzgerald, y otras fuentes.
He encontrado algunas definiciones para el concepto de expresiones regulares, por ejemplo la Wikipedia y he encontrado algo como lo que sigue:
Nota
Es importante ejecutar o construir el código para ir avanzado de lo más simple a lo complejo y notar como el motor de C# hace uso de las expresiones regulares. He usado el libro, "Introducing Regular Expressions", Editorial O'REILLY, Michael Fitzgerald, y otras fuentes.
He encontrado algunas definiciones para el concepto de expresiones regulares, por ejemplo la Wikipedia y he encontrado algo como lo que sigue:
Una expresión regular, a menudo llamada también regex, es una secuencia de caracteres que forma un patrón de búsqueda, principalmente utilizada para la búsqueda de patrones de cadenas de caracteres u operaciones de sustituciones.
Otro ejemplo tomado del libro, "Introducing Regular Expressions", Editorial O'REILLY, Michael Fitzgerald.
Las expresiones regulares son cadenas de texto especialmente codificadas usadas como patrones para encontrar las coincidencias dentro de otra cadena de texto.
Las expresiones regulares son cadenas de texto..., es decir son letras, números y símbolos que usamos de forma cotidiana en nuestra escritura...
especialmente codificadas... cuando decimos que son "codificadas", significa que usamos un "código" y un código tiene las siguientes acepciones, según la RAE (Real Academia Española) -he colocado en negritas la acepción que considero adecuada a nuestro tema tratado-.
Del lat. codex, -ĭcis 'código' y -ficar.1. tr. Hacer o formar un cuerpo de leyes metódico y sistemático.2. tr. Transformar mediante las reglas de un código la formulación de un mensaje.3. tr. Registrar algo siguiendo un código (‖ combinación de letras, números u otroscaracteres).
Es decir que usamos las letras, números y símbolos de acuerdo a reglas (leyes) de forma metódica y sistemática y transformamos mediante estas reglas el mensaje que deseamos armar, construir, o escribir, y lo hacemos para comunicarnos en el mundo de las expresiones regulares.
Así que cuando escribimos estas expresiones seguimos un código, y decimos entonces que están codificadas, y podemos decir que son especiales porque las reglas para su escrituras no son del uso cotidiano o común.
usadas como patrones... la palabra "patrón" creo que debe ser clarificada y nuevamente me auxiliare del diccionario de la RAE (he colocado en negritas la acepción que considero adecuada a nuestro tema tratado).
patrón
Del lat. patrōnus; la forma f., del lat. patrōna.En acep. 7, u. t. el m. para referirse a una mujer.1. m. y f. Defensor, protector.2. m. y f. Santo titular de una iglesia.3. m. y f. Santo elegido como protector de un pueblo o congregación religiosa, profesional ocivil.4. m. y f. Dueño de la casa donde alguien se aloja u hospeda.5. m. y f. señor (‖ persona a la que sirve un criado).6. m. y f. patrono (‖ persona que emplea trabajadores).7. m. y f. Persona que manda un pequeño buque mercante o una embarcación de recreo.8. m. Modelo que sirve de muestra para sacar otra cosa igual.9. m. Metal que se toma como tipo para la evaluación de la moneda en un sistema monetario.10. m. Planta en que se hace un injerto.11. f. Galera inmediatamente inferior en dignidad a la capitana de una escuadra.
Entonces un patrón es un modelo, entonces, cada vez que escribimos un cadena de texto que sigue las reglas de escritura del mundo de las expresiones regulares buscamos sacar otra cosa igual y lo hacemos colocando nuestro modelo frente a otras cadenas de texto mediante una aplicación.
Así que ahora sabemos que el objetivo que siguen las expresiones regulares es encontrar coincidencias dentro de otras cadenas de texto.
Las expresiones regulares datan de la década de 1940 pero se usan en el mundo de la programación en la década de 1970. Tienen un uso intenso en editores de texto de UNIX como; ed, sed, vi y otros. Además de ser un tema del examen de certificación, 70-483 Programming in C# de Microsoft.
Usare una aplicación de C# haciendo uso del motor de expresiones regulares de .NET, Regex MSDN Microsoft, este motor es definido como sigue:
El Regex clase representa el motor de expresiones regulares de .NET Framework.Se puede utilizar para analizar rápidamente grandes cantidades de texto para buscar modelos de caracteres específicos; para extraer, modificar, reemplazar o eliminar subcadenas de texto; y para agregar las cadenas extraídas a una colección para generar un informe.
En la aplicación de ejemplo avanzaremos en el uso de expresiones regulares desde lo más simple hacia lo complejo, tomando en cuenta que es una introducción. El ejemplo no tiene control de ciclo y se ejecuta con CTRL+F5.
Ejemplo:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace ExprecionesRegularesIntro
{
class Program
{
static void Main(string[] args)
{
// Buscaremos las coincidencias o Match
// en la cadena de los digitos del 0 al 9
// y se expresa asi: [0-9]
// se le llama: character class o character set
//ContieneAlaExpresion("abcd123efg", @"[0-9]");
// Puede limitarse el rango, especificando
// que digitos deseamos.
//ContieneAlaExpresion("abcd123efg", @"[12]");
// Buscaremos las coincidencias en un número
// con la siguiente estructura 044-55-1234-5678
//ContieneAlaExpresion("055-44-5678-1234",
// @"[0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]");
// Buscaremos las coincidencias en un número
// con la siguiente estructura 044-55-1234-5678
// pero la ahora hemos colocado letras en la cadena
// para hacer notar que no se encontraron Match
//ContieneAlaExpresion("04a-5b-a234-z678",
// @"[0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]");
// Una forma más rápida y simple es usar
// \b - este character shorthand (simbolo taquigrafico o caracter taquigrafico)
// busca las coincidencias de cualquier digito de: 0 a 9
//ContieneAlaExpresion("abcd123efg", @"\d");
// Ahora usaremos: \b
// Buscaremos las coincidencias en un número
// con la siguiente estructura 044-55-1234-5678
//ContieneAlaExpresion("044-54-1234-8678",
// @"\d\d\d-\d\d-\d\d\d\d-\d\d\d\d");
// Ahora usaremos: \b
// Buscaremos las coincidencias en un número
// con la siguiente estructura 044-55-1234-5678
//ContieneAlaExpresion("a44-54-b234-8678",
// @"\d\d\d-\d\d-\d\d\d\d-\d\d\d\d");
// Ahora usaremos: \b ... asi mismo: \D
// Hemos usado el guión: "-" de forma directa
// pero podemos usar: \D que define cualquier caracter que
// no sea un numero.
// Pruebe colocando una letra en vez de cualquier numero
// para ver el efecto del Match
//ContieneAlaExpresion("044-54-1234-8678",
// @"\d\d\d\D\d\d\D\d\d\d\d\D\d\d\d\d");
// Ahora usaremos: \b ... podemos usar el caracter punto: "."
// el caracter punto es un comodin y puede representar
// cualquier caracter (excepto en ciertas situaciones, al fin de linea)
// Pruebe colocando una letra en vez de cualquier numero
// para ver el efecto del Match
//ContieneAlaExpresion("044-54-1234-8678",
// @"\d\d\d.\d\d.\d\d\d\d.\d\d\d\d");
//ContieneAlaExpresion("044|54|1234|8678",
// @"d\d\d.\d\d.\d\d\d\d.\d\d\d\d");
//ContieneAlaExpresion("044%54%1234%8678",
// @"\d\d\d.\d\d.\d\d\d\d.\d\d\d\d");
// USANDO CUANTIFICADORES (se ha utilizado nuevamente el guión: "-")
// los numeros entre llaves: {} definen cuantos digitos
// deberan aparecer en la cadena evaluada.
//
// El uso de cuantificadores hace más concisa la expresión.
//
// el simbolo: ? es otro cuantificador y al aparecer despues del guion ("-")
// significa que este es opcional, es decir, puede o no estar presente.
// Pruebe retirando el guion de la cadena para ver el efecto.
//ContieneAlaExpresion("044-54-1234-8678",
// @"\d{3}-?\d{2}-?\d{4}-\d{4}");
// Pruebe el uso de la expresion con diferentes opciones en la cadena
// conla que se hace el Match
//
// Explicación del uso de la expresion siguiente y sus cauntificadores.
// ( ... inicia una agrupación
// \ ... define el inicio del uso de un caracter taquigrafico (character shorthand)
// d ... define el caracter taquigrafico y marca el fin del uso del mismo.
// { ... inicia el cuantificador de cantidad de caracteres.
// 2 ... minima cantidad de caracteres que coincidan.
// , ... el separador de cantidad.
// 4 ... máxima cantidad de caracteres que coincidan.
// } ... cierre del cuantiquicador
// [ ... define el inicio de una agrupación de caracteres que se toman
// de forma literal, sin aplicar las reglas de las expresiones regulares
// y se conoce como: clase de caracteres
// . ... define que se usara el caracter punto (" . ")
// - ... define el uso del guión (" - " )
// ] ... cierre de la: clase de caracteres
// ? ... cero o un cuantificador, puede o no aparecer, en este caso un guión o
// un punto
// ) ... cierre de grupo
// + ... uno o mas cuantiicadores
// Pruebe retirando el guion de la cadena para ver el efecto.
// se han colocado mas numeros y la coicidencia es localizada
//ContieneAlaExpresion("044.54.1234-8678-4512-9999-45",
// @"(\d{2,4}[.-]?)+");
// en el ejemplo anterior se observo que la coincidencia se produce
// pero si deseamos tener una evaluación estricta de un numero con
// vamos a mejorar un poco la expresión.
// Observe que la cadena puede ser mas larga y el motor
// mandara coincidencia.
//ContieneAlaExpresion("044-54-1234-8678",
// @"\d{3}[.-]?\d{2}[.-]?(\d{4}[.-]?){2}");
// Ahora vamos a definir que los primeros tres caracteres de la cadena
// sean opcionales de aparecer: 044
// el resultado es que hay coincidencia, en los dos primeros y el tercero no.
//ContieneAlaExpresion("55-1234-8678",
// @"(\d{3}[.-])?\d{2}[.-]?(\d{4}[.-]?)\d{4}");
//ContieneAlaExpresion("044-55-1234-8678",
// @"(\d{3}[.-])?\d{2}[.-]?(\d{4}[.-]?)\d{4}");
//ContieneAlaExpresion("1234-8678",
// @"(\d{3}[.-])?\d{2}[.-]?(\d{4}[.-]?)\d{4}"); // no hay coincidencia
// Ahora
// 1er. ESTRICTO inicio de la cadena
// y ademas con tres numeros, en este caso: 044
// tambien limitamos que aparezcan numeros o guiones al inicio de
// la cadena.
//ContieneAlaExpresion("55-1234-8678",
// @"^(\d{3}[.-])\d{2}[.-]?(\d{4}[.-]?)\d{4}"); // NO hay coincidencia
// 2. ESTRICTO inicio donde los primeros tres caracteres de la cadena
// deben aparecer.
//ContieneAlaExpresion("044-55-1234-8678",
// @"^(\d{3}[.-])\d{2}[.-]?(\d{4}[.-]?)\d{4}"); // hay coincidencia
// 3. Se marca INICIO, donde los primeros tres caracteres de la cadena
// puden o no parecer, pero se define que es inicio de cadena
//ContieneAlaExpresion("044-55-1234-8678",
// @"^(\d{3}[.-])\d{2}[.-]?(\d{4}[.-]?)\d{4}"); // hay coincidencia
//ContieneAlaExpresion("55-1234-8678",
// @"^(\d{3}[.-])?\d{2}[.-]?(\d{4}[.-]?)\d{4}"); // hay coincidencia
//4. INICIO donde los primeros tres caracteres de la cadena
//puden o no parecer, pero no otros caracteres.
//ContieneAlaExpresion("22-044-55-1234-8678",
// @"^(\d{3}[.-])?\d{2}[.-]?(\d{4}[.-]?)\d{4}"); // NO hay coincidencia
//ContieneAlaExpresion("044-55-1234-8678",
// @"^(\d{3}[.-])\d{2}[.-]?(\d{4}[.-]?)\d{4}"); // hay coincidencia
//ContieneAlaExpresion("55-1234-8678",
// @"^(\d{3}[.-])?\d{2}[.-]?(\d{4}[.-]?)\d{4}"); // hay coincidencia
// 5. Ahora definiremos el fin de la cadena
// para hacer Match ... el caracer utilizado es: $
//ContieneAlaExpresion("044-55-1234-8678",
// @"^(\d{3}[.-])?\d{2}[.-]?(\d{4}[.-]?)\d{4}$"); // HAY coincidencia
//ContieneAlaExpresion("044-55-1234-8678-",
// @"^(\d{3}[.-])?\d{2}[.-]?(\d{4}[.-]?)\d{4}$"); // NO hay coincidencia
//ContieneAlaExpresion("044-55-1234-8678-22",
// @"^(\d{3}[.-])?\d{2}[.-]?(\d{4}[.-]?)\d{4}$"); // NO hay coincidencia
// finalmente hemos conseguido que la cadena coincida con un
// la estructura de los numeros celulares de la ciudad de México
// de forma estricta.
// Existen mejoras para la expresión pero eso se vera
// en un nuevo tema, más avanzado.
}
static void ContieneAlaExpresion(string inputData, string regExPattern)
{
Console.WriteLine("Buscando coindidencias en ..." + inputData);
Console.WriteLine();
Regex rgx = new Regex(regExPattern, RegexOptions.ExplicitCapture);
MatchCollection matches = rgx.Matches(inputData);
if (matches.Count > 0)
{
Console.WriteLine("HAY coincidencias en: {0} ... se encontraron: {1} y son:", inputData, matches.Count);
Console.WriteLine();
foreach (Match match in matches)
Console.WriteLine(" " + match.Value);
}
else { Console.WriteLine("NO HAY elementos coincidentes."); }
Console.WriteLine();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace ExprecionesRegularesIntro
{
class Program
{
static void Main(string[] args)
{
// Buscaremos las coincidencias o Match
// en la cadena de los digitos del 0 al 9
// y se expresa asi: [0-9]
// se le llama: character class o character set
//ContieneAlaExpresion("abcd123efg", @"[0-9]");
// Puede limitarse el rango, especificando
// que digitos deseamos.
//ContieneAlaExpresion("abcd123efg", @"[12]");
// Buscaremos las coincidencias en un número
// con la siguiente estructura 044-55-1234-5678
//ContieneAlaExpresion("055-44-5678-1234",
// @"[0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]");
// Buscaremos las coincidencias en un número
// con la siguiente estructura 044-55-1234-5678
// pero la ahora hemos colocado letras en la cadena
// para hacer notar que no se encontraron Match
//ContieneAlaExpresion("04a-5b-a234-z678",
// @"[0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]");
// Una forma más rápida y simple es usar
// \b - este character shorthand (simbolo taquigrafico o caracter taquigrafico)
// busca las coincidencias de cualquier digito de: 0 a 9
//ContieneAlaExpresion("abcd123efg", @"\d");
// Ahora usaremos: \b
// Buscaremos las coincidencias en un número
// con la siguiente estructura 044-55-1234-5678
//ContieneAlaExpresion("044-54-1234-8678",
// @"\d\d\d-\d\d-\d\d\d\d-\d\d\d\d");
// Ahora usaremos: \b
// Buscaremos las coincidencias en un número
// con la siguiente estructura 044-55-1234-5678
//ContieneAlaExpresion("a44-54-b234-8678",
// @"\d\d\d-\d\d-\d\d\d\d-\d\d\d\d");
// Ahora usaremos: \b ... asi mismo: \D
// Hemos usado el guión: "-" de forma directa
// pero podemos usar: \D que define cualquier caracter que
// no sea un numero.
// Pruebe colocando una letra en vez de cualquier numero
// para ver el efecto del Match
//ContieneAlaExpresion("044-54-1234-8678",
// @"\d\d\d\D\d\d\D\d\d\d\d\D\d\d\d\d");
// Ahora usaremos: \b ... podemos usar el caracter punto: "."
// el caracter punto es un comodin y puede representar
// cualquier caracter (excepto en ciertas situaciones, al fin de linea)
// Pruebe colocando una letra en vez de cualquier numero
// para ver el efecto del Match
//ContieneAlaExpresion("044-54-1234-8678",
// @"\d\d\d.\d\d.\d\d\d\d.\d\d\d\d");
//ContieneAlaExpresion("044|54|1234|8678",
// @"d\d\d.\d\d.\d\d\d\d.\d\d\d\d");
//ContieneAlaExpresion("044%54%1234%8678",
// @"\d\d\d.\d\d.\d\d\d\d.\d\d\d\d");
// USANDO CUANTIFICADORES (se ha utilizado nuevamente el guión: "-")
// los numeros entre llaves: {} definen cuantos digitos
// deberan aparecer en la cadena evaluada.
//
// El uso de cuantificadores hace más concisa la expresión.
//
// el simbolo: ? es otro cuantificador y al aparecer despues del guion ("-")
// significa que este es opcional, es decir, puede o no estar presente.
// Pruebe retirando el guion de la cadena para ver el efecto.
//ContieneAlaExpresion("044-54-1234-8678",
// @"\d{3}-?\d{2}-?\d{4}-\d{4}");
// Pruebe el uso de la expresion con diferentes opciones en la cadena
// conla que se hace el Match
//
// Explicación del uso de la expresion siguiente y sus cauntificadores.
// ( ... inicia una agrupación
// \ ... define el inicio del uso de un caracter taquigrafico (character shorthand)
// d ... define el caracter taquigrafico y marca el fin del uso del mismo.
// { ... inicia el cuantificador de cantidad de caracteres.
// 2 ... minima cantidad de caracteres que coincidan.
// , ... el separador de cantidad.
// 4 ... máxima cantidad de caracteres que coincidan.
// } ... cierre del cuantiquicador
// [ ... define el inicio de una agrupación de caracteres que se toman
// de forma literal, sin aplicar las reglas de las expresiones regulares
// y se conoce como: clase de caracteres
// . ... define que se usara el caracter punto (" . ")
// - ... define el uso del guión (" - " )
// ] ... cierre de la: clase de caracteres
// ? ... cero o un cuantificador, puede o no aparecer, en este caso un guión o
// un punto
// ) ... cierre de grupo
// + ... uno o mas cuantiicadores
// Pruebe retirando el guion de la cadena para ver el efecto.
// se han colocado mas numeros y la coicidencia es localizada
//ContieneAlaExpresion("044.54.1234-8678-4512-9999-45",
// @"(\d{2,4}[.-]?)+");
// en el ejemplo anterior se observo que la coincidencia se produce
// pero si deseamos tener una evaluación estricta de un numero con
// vamos a mejorar un poco la expresión.
// Observe que la cadena puede ser mas larga y el motor
// mandara coincidencia.
//ContieneAlaExpresion("044-54-1234-8678",
// @"\d{3}[.-]?\d{2}[.-]?(\d{4}[.-]?){2}");
// Ahora vamos a definir que los primeros tres caracteres de la cadena
// sean opcionales de aparecer: 044
// el resultado es que hay coincidencia, en los dos primeros y el tercero no.
//ContieneAlaExpresion("55-1234-8678",
// @"(\d{3}[.-])?\d{2}[.-]?(\d{4}[.-]?)\d{4}");
//ContieneAlaExpresion("044-55-1234-8678",
// @"(\d{3}[.-])?\d{2}[.-]?(\d{4}[.-]?)\d{4}");
//ContieneAlaExpresion("1234-8678",
// @"(\d{3}[.-])?\d{2}[.-]?(\d{4}[.-]?)\d{4}"); // no hay coincidencia
// Ahora
// 1er. ESTRICTO inicio de la cadena
// y ademas con tres numeros, en este caso: 044
// tambien limitamos que aparezcan numeros o guiones al inicio de
// la cadena.
//ContieneAlaExpresion("55-1234-8678",
// @"^(\d{3}[.-])\d{2}[.-]?(\d{4}[.-]?)\d{4}"); // NO hay coincidencia
// 2. ESTRICTO inicio donde los primeros tres caracteres de la cadena
// deben aparecer.
//ContieneAlaExpresion("044-55-1234-8678",
// @"^(\d{3}[.-])\d{2}[.-]?(\d{4}[.-]?)\d{4}"); // hay coincidencia
// 3. Se marca INICIO, donde los primeros tres caracteres de la cadena
// puden o no parecer, pero se define que es inicio de cadena
//ContieneAlaExpresion("044-55-1234-8678",
// @"^(\d{3}[.-])\d{2}[.-]?(\d{4}[.-]?)\d{4}"); // hay coincidencia
//ContieneAlaExpresion("55-1234-8678",
// @"^(\d{3}[.-])?\d{2}[.-]?(\d{4}[.-]?)\d{4}"); // hay coincidencia
//4. INICIO donde los primeros tres caracteres de la cadena
//puden o no parecer, pero no otros caracteres.
//ContieneAlaExpresion("22-044-55-1234-8678",
// @"^(\d{3}[.-])?\d{2}[.-]?(\d{4}[.-]?)\d{4}"); // NO hay coincidencia
//ContieneAlaExpresion("044-55-1234-8678",
// @"^(\d{3}[.-])\d{2}[.-]?(\d{4}[.-]?)\d{4}"); // hay coincidencia
//ContieneAlaExpresion("55-1234-8678",
// @"^(\d{3}[.-])?\d{2}[.-]?(\d{4}[.-]?)\d{4}"); // hay coincidencia
// 5. Ahora definiremos el fin de la cadena
// para hacer Match ... el caracer utilizado es: $
//ContieneAlaExpresion("044-55-1234-8678",
// @"^(\d{3}[.-])?\d{2}[.-]?(\d{4}[.-]?)\d{4}$"); // HAY coincidencia
//ContieneAlaExpresion("044-55-1234-8678-",
// @"^(\d{3}[.-])?\d{2}[.-]?(\d{4}[.-]?)\d{4}$"); // NO hay coincidencia
//ContieneAlaExpresion("044-55-1234-8678-22",
// @"^(\d{3}[.-])?\d{2}[.-]?(\d{4}[.-]?)\d{4}$"); // NO hay coincidencia
// finalmente hemos conseguido que la cadena coincida con un
// la estructura de los numeros celulares de la ciudad de México
// de forma estricta.
// Existen mejoras para la expresión pero eso se vera
// en un nuevo tema, más avanzado.
}
static void ContieneAlaExpresion(string inputData, string regExPattern)
{
Console.WriteLine("Buscando coindidencias en ..." + inputData);
Console.WriteLine();
Regex rgx = new Regex(regExPattern, RegexOptions.ExplicitCapture);
MatchCollection matches = rgx.Matches(inputData);
if (matches.Count > 0)
{
Console.WriteLine("HAY coincidencias en: {0} ... se encontraron: {1} y son:", inputData, matches.Count);
Console.WriteLine();
foreach (Match match in matches)
Console.WriteLine(" " + match.Value);
}
else { Console.WriteLine("NO HAY elementos coincidentes."); }
Console.WriteLine();
}
}
}
No hay comentarios.:
Publicar un comentario