2009-03-24 17 views

Respuesta

45

Según Generate a Regular Expression to Match an Arbitrary Numeric Range, y después de generar una expresión regular como por su ejemplo en Regex_For_Range:

\b0*(1[1-9][0-9]|[2-9][0-9]{2}|1[0-9]{3}|2[01][0-9]{2}|22[0-2][0-9]|223[0-4])\b 

que hacer el truco.

el proceso sería (todavía siguiendo ese generador Regex):

En primer lugar, se rompe en la misma longitud oscila:

110 - 999 
1000 - 2234 

En segundo lugar, romper en rangos que producen expresiones regulares simples :

110 - 199 
200 - 999 
1000 - 1999 
2000 - 2199 
2200 - 2229 
2230 - 2234 

Turn cada rango en una expresión regular:

1[1-9][0-9] 
[2-9][0-9]{2} 
1[0-9]{3} 
2[01][0-9]{2} 
22[0-2][0-9] 
223[0-4] 

Collapse poderes adyacentes de 10: 1 [1-9] [0-9] [2-9] [0- 9] {2} 1 [0-9] {3} 2 [01] [0-9] {2} 22 [0-2] [0-9] 223 [0-4]

Combinando las expresiones regulares anteriores rendimientos:

0*(1[1-9][0-9]|[2-9][0-9]{2}|1[0-9]{3}|2[01][0-9]{2}|22[0-2][0-9]|223[0-4]) 

A continuación vamos a tratar de factorizar prefijos comunes utilizando un árbol:
Analizar en el árbol basado en prefijos de expresiones regulares:

. 1 [1-9] [0-9] 
+ [0-9]{3} 
+ [2-9] [0-9]{2} 
+ 2 [01] [0-9]{2} 
+ 2 [0-2] [0-9] 
+ 3 [0-4] 

gira el árbol de análisis sintáctico en una regex yields:

0*(1([1-9][0-9]|[0-9]{3})|[2-9][0-9]{2}|2([01][0-9]{2}|2([0-2][0-9]|3[0-4]))) 

Elegimos el más corto como resultado.

\b0*(1[1-9][0-9]|[2-9][0-9]{2}|1[0-9]{3}|2[01][0-9]{2}|22[0-2][0-9]|223[0-4])\b 
+0

A C#/VB.NET/PHP o cualquier otro idioma, excepto el que no sé sería genial. ;) – Echilon

+14

+1 para ambos impresionante y un poco de miedo. – joshin4colours

+0

por cierto, esto coincidiría con 000, 001, 010, etc. – insaner

17

Este no es el tipo de cosas en las que las expresiones regulares se destacan. Probablemente le resulte más fácil asegurarse de tener el número correcto de dígitos /^([0-9]{3,4})$/ y luego hacer más comprobaciones en contra de la captura.

3

Es posible que no sea bonita.

\b(?:[1][1][0-9]|1\d{3}|223[0-4]|2[0-1]\d\d|2[0-2][0-3][0-4])\b 

le envié un correo Phillip Hazel, el autor de PCRE, en 2006 lo que pensaba de matemáticas de en expresiones regulares:

Tal vez esto está fuera del alcance del proyecto en su opinión: La capacidad de Trate los números como números y no como texto, esto definitivamente sería una característica que vale la pena. permitiéndole hacer algunas comprobaciones matemáticas básicas en los dígitos coincidentes, como: ¿es el segundo dígito combinado más alto o más bajo, es el tercer dígito un múltiplo del primero, y muchos casos más complicados que no elaboraré solo para entender mi punto al otro lado. ¿Siente que esto excede el ámbito de la combinación de textos?

a la que tiene la siguiente respuesta:

Sí, creo que sí, y también, no es algo que está disponible en Perl expresiones regulares. Yo sé que PCRE tiene algunas extensiones de Perl, pero nada tan importante como el de ( que tal vez podrían piratear algo usando llamadas, pero eso sería un poco ad hoc , y sin duda muy sucio!).

Philip

y no podría estar más de acuerdo ahora en `09. Simplemente haga coincidir todos los números y valide los números en el idioma con el que esté haciendo la coincidencia.

+0

Me resistí a corregir la ortografía de la cita, pero no quiero que se propaguen los memes ortográficos incorrectos. – Svante

+0

Esto no coincidiría con los números en el rango 120-199 – insaner

4

Mientras que usted podría hacerlo con un poco de expresiones regulares en busca absurdo (como respondió VonC), expresiones regulares no se supone realmente para hacer esto .. ¿Por qué no aplazar el número de cheques a la-a-redirigida ¿guión?

Si los números 110-2234 van a script1 y 1-109 van a SCRIPT2, sería mucho más fácil de dirigir todos los números en una secuencia de comandos router, y tienen que redirigir a la ubicación correcta (a través de redirecciones HTTP) ..

En .htaccess:

RewriteRule ^view/([0-9]+)/?$ router.php?page=$1 [L] 

..a continuación, en router.php, algo así como:

<?PHP 
if(
    int($_GET['page']) > 110 && 
    int($_GET['page']) < 2234 
){ 
    header("Status: 301 Moved Permanently\nLocation: /script1"); 
}else{ 
    header("Status: 404 Not Found"); 
} 
?> 
+0

Lo sé. Me gustaría hacerlo en .htaccess y evitar cargar php y simplemente cargar el archivo estático correcto :-) – barredo

+0

¡Pero gracias por la respuesta! :-) – barredo

3

Usted puede poner las expresiones regulares para los siguientes rangos juntos:

1[1-9]\d = 110-199 
[2-9]\d\d = 200-999 
1\d\d\d = 1000-1999 
2[0-1]\d\d= 2000-2199 
22[0-2]\d = 2200-2229 
223[0-4] = 2230-2234 

para formar:

(1[1-9]\d|[2-9]\d\d|1\d\d\d|2[0-1]\d\d|22[0-2]\d|223[0-4]) 

\ medio d [0-9 ], pero en tres caracteres menos

Cuestiones relacionadas