PDA

Ver la Versión Completa : Expresiones Regulares (¿o Regular Expressions?)


Ñuño Martínez
09-10-2006, 15:47:10
La verdad, no sabía dónde poner esto así que lo he metido en "Varios".

El tema es que últimamente estoy escuchando y leyendo muchas veces lo de las "expresiones regulares" y las "regular expressions" (que digo yo que son lo mismo, ¿no?). Creo que sé lo que es: un lenguaje que permite definir patrones o plantillas para búsquedas o introducción de texto. Algo así como la BNF, ¿o no?

Pues eso, ¿dónde puedo aprender qué es y cómo utilizar expresiones regulares, tanto con las funciones/objetos que pueda tener Delphi como con otras librerías/lenguajes (especialmente Pascal, C y PHP), utilidades com grep y tal? ¿Qué ventajas tiene? ¿Existen alternativas?

Ñuño Martínez
11-10-2006, 10:34:56
¿Ninguna ayudita? No me digan que no saben nada de esto, que no me lo creo, ¿eh? ;)

Bicho
11-10-2006, 10:54:50
Hola, pues yo tampoco tengo ni idea de lo que son y por lo que leo en el ClubDelphi, todo el mundo habla maravillas de ello.

Y como no la Wikipedia (http://es.wikipedia.org/) tiene la solucion:

Expresión regular (http://es.wikipedia.org/wiki/Expresi%C3%B3n_regular)

Tambien buscando un poco por los foros he encontrado un par de hilos que quiza puedan ser interesantes:

Regexp... ?? (http://www.clubdelphi.com/foros/showthread.php?t=11577&highlight=expresiones+regulares)

Guia de herramientas para programadores! (http://www.clubdelphi.com/foros/showthread.php?t=35578&highlight=expresiones+regulares)

Así que nos toca empezar a leer.

Espero sirva para empezar

Saludos

Ñuño Martínez
11-10-2006, 11:08:18
Gracias Bisho.

¡Cuándo aprenderé que hay que usar los buscadores antes de hacer preguntas tontas!:o

Bicho
11-10-2006, 11:35:40
¡Cuándo aprenderé que hay que usar los buscadores antes de hacer preguntas tontas!

Cuando aprendas que mi nick es Bicho y no Bisho, que no soy andalús!! leshe!! :D soy mallorquín!! :p

Es coña, eh?

En cuanto a lo de las preguntas tontas, no dicen algo así como no hay mayor ignorante que el que no pregunta? Tu ya has preguntado y ya sabes algo más no?

Además la pregunta no ha sido tonta, a mí me ha servido para (además de ponerme a buscar :rolleyes: ) para aprender algo nuevo.

Saludos

Lepe
11-10-2006, 15:28:24
Ya teneís links "más profesionales", aquí solo expongo una idea general para saber si es lo que necesitaís o no.

-El propio delphi tiene rutinas para crear expresiones regulares.
- Lex es una analizador léxico (que tiene una versión en delphi)
- Yacc es un analizador sintáctico (que tambien existe en version delphi)

¿Y qué demonios son analizadores lexico/sintactico?

analizador lexico:
[a..z]+ : mostrar('el usuario ha escrito al menos una letra desde la a a la z');
[0..9]+ : mostrar('el usuario ha escrito al menos un número');
[a..z]+[0..9]+ : mostrar(' el usuario ha escrito al menos una letra y despues un número');

Es decir, se puede "adivinar" lo que el usuario va escribiendo, vamos el típico caso de escribir en Word: "Estimado Señor:" y salta el asistente de office diciendo: "Veo que está escribiendo una carta, ¿necesita ayuda?

[a..z]+ es lo que se llama una expresión regular, que se validará solo cuando el usuario pulse una o más letras pertenecientes al rango a..z

Analizador sintáctico:
Es el encargado de verificar el orden en el que se han escrito las palabras. Si el usuario escribe : "Señor Estimado:" no debe saltar el asistente de office, porque no se ha escrito en el orden correcto. Este analizador sólo se encarga del Orden, por ejemplo:


Sacar_Asistente_ si: "Estimado señor:" o bien
"Estimados señores:" o bien
"Estimado Cliente:" o bien
"Estimado amigo:"




Aunque muchos no os lo creaís, me atrevo decir que es el futuro de la programación: Detectar qué quiere el usuario en cada momento para brindarle ayuda o asistentes paso a paso y no complicarles la vida en inmensos archivos hlp.

Por cierto, ¿como creeís que se obtienen las partes de un SQL?
SELECT nombrecampos FROM nombretablas WHERE condiciones HAVING ... ORDER BY
A través de un Parser se buscan los tokens (palabras reservadas SELECT, FROM, WHERE,ect) y se validan sin son correctas sintácticamente o no.

Saludos

roman
11-10-2006, 17:12:14
Para entender de qué van las expresiones regulares quizá te sirva este mensaje (http://www.clubdelphi.com/foros/showpost.php?p=121034&postcount=11) y si no, por lo menos el tutorial que enlazo al final del mismo. Se trata de las expresiones regulares tipo P_E_R_L (o sea, las que se usan en P_E_R_L) que son muy populares. El tutorial en cuestión, es para el uso de las expresiones en PHP aunque es buena introducción general.

En cuanto a:


El propio delphi tiene rutinas para crear expresiones regulares.


Pues sí que me sorprende; hasta donde yo sé, es una de las grandes carencias de Delphi. Claro que existen componentes y clases de terceros, muchas de las cuales ya se han mencionado aquí y en los foros en general. Lo más cercano a expresiones regulares que he visto en Delphi es el MatchesMask de la unidad Mask, pero es francamente limitado.

Y en cuanto a esto:


me atrevo decir que es el futuro de la programación: Detectar qué quiere el usuario en cada momento para brindarle ayuda o asistentes paso a paso y no complicarles la vida en inmensos archivos hlp.


Por dios, espero que no, bastante fastidioso es el ayudante de office diciendome a cada momento que quiero escribir una carta.

// Saludos

Bicho
11-10-2006, 23:55:30
Muchas gracias Lepe y Roman por sus lecciones magistrales y sus links de gran interés.

La verdad es que ahora queda mucho más claro todo.

Saludos

Lepe
12-10-2006, 15:16:05
roman: supongo que conoces la unidad ConvUtils.pas, donde se puede crear conversiones entre unidades de medida, pesos, etc. Pues juraría que he visto la misma filosofía con expresiones regulares en Delphi 6 hace un par de años, lo encontré de pasada y no entendí la filosofía de uso, así que lo descarté.

Usando el Grep Search de GExpert he obtenido algunas cosas:

En BDS 2006 en la unidad Nsapi.pas, solo he podido encontrar esto:
{*****************************************************************************}
{* From shexp.h }
{*****************************************************************************}
{
Defines and prototypes for shell exp. match routines


This routine will match a string with a shell expression. The expressions
accepted are based loosely on the expressions accepted by zsh.

o * matches anything
o ? matches one character
o \ will escape a special character
o $ matches the end of the string
o [abc] matches one occurence of a, b, or c. The only character that needs
to be escaped in this is ], all others are not special.
o [a-z] matches any character between a and z
o [^az] matches any character except a or z
o ~ followed by another shell expression will remove any pattern
matching the shell expression from the match list
o (foo|bar) will match either the substring foo, or the substring bar.
These can be shell expressions as well.

The public interface to these routines is documented below.
}

{* --------------------------- Public routines ---------------------------- *}

{
shexp_valid takes a shell expression exp as input. It returns:

NON_SXP if exp is a standard string
INVALID_SXP if exp is a shell expression, but invalid
VALID_SXP if exp is a valid shell expression
}

const
NON_SXP = -1;
INVALID_SXP = -2;
VALID_SXP = 1;

{* and generic shexp/regexp versions *}
NON_WILDPAT = NON_SXP;
INVALID_WILDPAT = INVALID_SXP;
VALID_WILDPAT = VALID_SXP;

{* and regexp versions *}
NON_REGEXP = NON_SXP;
INVALID_REGEXP = INVALID_SXP;
VALID_REGEXP = VALID_SXP;

function shexp_valid(exp: PChar): Integer; cdecl;

{
shexp_match

Takes a prevalidated shell expression exp, and a string str.

Returns 0 on match and 1 on non-match.
}
function shexp_match(str, exp: PChar): Integer; cdecl;

{
shexp_cmp

Same as above, but validates the exp first. 0 on match, 1 on non-match,
-1 on invalid exp. shexp_casecmp does the same thing but is case
insensitive.
}
function shexp_cmp(str, exp: PChar): Integer; cdecl;
function shexp_casecmp(str, exp: PChar): Integer; cdecl;
****************************
function shexp_valid; external nshttp name 'shexp_valid';
function shexp_match; external nshttp name 'shexp_match';
function shexp_cmp; external nshttp name 'shexp_cmp';
function shexp_casecmp; external nshttp name 'shexp_casecmp';
****************************


En la unidad ToolsApi.pas he encontrado esto, aunque el prefijo "IOTA" me deja KO.

IOTASearchOptions = interface(IUnknown)
['{D1766F8B-D915-11D2-A8C1-00C04FA32F53}']
function GetCaseSensitive: Boolean;
function GetDirection: TSearchDirection;
function GetFromCursor: Boolean;
function GetRegularExpression: Boolean;
function GetSearchText: string;
function GetWholeFile: Boolean;
function GetWordBoundary: Boolean;
procedure SetCaseSensitive(Value: Boolean);
procedure SetDirection(Value: TSearchDirection);
procedure SetFromCursor(Value: Boolean);
procedure SetRegularExpression(Value: Boolean);
procedure SetSearchText(const Value: string);
procedure SetWholeFile(Value: Boolean);
procedure SetWordBoundary(Value: Boolean);

property CaseSensitive: Boolean read GetCaseSensitive write SetCaseSensitive;
property Direction: TSearchDirection read GetDirection write SetDirection;
property FromCursor: Boolean read GetFromCursor write SetFromCursor;
property RegularExpression: Boolean read GetRegularExpression write SetRegularExpression;
property SearchText: string read GetSearchText write SetSearchText;
property WholeFile: Boolean read GetWholeFile write SetWholeFile;
property WordBoundary: Boolean read GetWordBoundary write SetWordBoundary;
end;

En dotNet\rtl\Borland.Vcl.Masks.pas tambien he encontrado cosas, pero en Delphi 6 no estará, que precisamente es donde recuerdo haberlo visto.

¿Podrías realizar algunas búsquedas en Delphi 6 para comprobar si existen lo que he encontrado? Gracias.

Saludos

jachguate
12-10-2006, 17:41:36
En la unidad ToolsApi.pas he encontrado esto, aunque el prefijo "IOTA" me deja KO.

I => Interfaz
OTA => Open Tools API.

Estas cosas son útiles cuando te pones a jugar con la parte trasera del IDE de delphi.. :D

La interfaz en cuestión es la que usas cuando queres hacer una búsqueda, que por cierto, tiene una opción (limitada) para buscar usando expresiones regulares, lo que no quiere decir que podas usarlas desde el lenguaje... es decir, en tus propios programas. Como ya ha dicho roman, para esto hay componentes y bibliotecas de terceros.

Hasta luego.

;)

Lepe
13-10-2006, 15:33:51
Menos mal, me parecía que Borland me insultaba IdiOTA :D ;)

Ñuño Martínez
13-10-2006, 22:31:30
Gracias a todos. Ya sepo varias cosas más.

egostar
13-10-2006, 22:36:40
Menos mal, me parecía que Borland me insultaba IdiOTA :D ;)

y si mejor lo vieras como id IOTA, algo que imagino muchos usamos al diseñar campos de base de datos.:D

Saludos