En una expresión regular, lo normal es que cuando ponemos un par de paréntesis, queramos capturar la expresión que coincida con el patrón que indiquemos ahí dentro. Pero hay otras ocasiones en las que no queremos capturar nada. En nuestro caso, estamos usando los paréntesis para agrupar opciones, como en
(avenida|avda.), pero NO queremos capturar lo que hay ahí dentro. Solo usamos los paréntesis para usar luego el '|' de alternativas dentro de ellos.
Por eso ponemos la nomenclatura
(?: ... ) que sirve para indicar que
esos paréntesis no capturan, solo agrupan.
Y con
[.] estamos indicando un '.' literal, lo mismo que si lo hubiéramos escapado así:
\. .
Si sabes las calles que quieres capturar, las puedes meter todas en una expresión regular de alternativas:
Using perl Syntax Highlighting
#!/usr/bin/perl
use 5.010;
use strict;
use warnings;
use diagnostics;
my $cadena = 'avenida independencia al 800 pegar buscar mas 2 av. callao al 7 y buscar en calle callao el 2';
# Tipos de calle
my $tipo_calle = qr/(?:av(?:[.]|da[.]?|enida)?|c(?:[.]|alle(?:jón|juela)?)|rotonda|paseo)/i;
# Nombre de calles
my @calles = ('Callao','Independencia');
my $calles = join '|', @calles; # las unimos
my $calle = qr/(?:$calles)/i; # la exp. reg.
# Preposición / determinantes
my $separador = qr/(?:al|la|el|los)/i;
# Número
my $numero = qr/\d+/;
# Buscamos
while ($cadena =~ /$tipo_calle ($calle) $separador ($numero)/gi) {
say "Calle: [$1] Altura: [$2]";
}
Coloreado en 0.002 segundos, usando
GeSHi 1.0.8.4
Aquí dividimos el problema de crear una gran expresión regular, en crear exp. regulares más pequeñas. Por ejemplo, el tipo de calle es capaz de reconocer av., avda. avenida, c., calle, callejón, callejuela, rotonda y paseo.
La exp. reg. de las calles la construimos con la ayuda de join() y qr().
Al final, lo unimos todo en una sola exp. reg., donde además aprovechamos para indicar qué partículas queremos capturar (esta vez sí) al final: la calle y el número.
Más información en
perlre.