¿Cómo hacer coincidir números entre X e Y con expresiones regulares?

Me gustaría hacer coincidir con RegExp un número entre X e Y. ¿Es eso posible?

([0-9] +) coincidirá con cualquier número, ¿cómo podría hacer para hacer coincidir un número entre, por ejemplo, 110 y 2234?

De acuerdo con Generar una expresión regular para que coincida con un rango numérico arbitrario , y después de generar dicha expresión regular para 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 

Haría el truco.

El proceso sería (siguiendo a ese generador Regex):

Primero, divide en rangos de igual longitud:

 110 - 999 1000 - 2234 

En segundo lugar, divida los rangos que producen expresiones simples:

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

Convierte 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] 

Contraer 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 los regexes anteriores rinde:

 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, intentaremos factorizar los prefijos comunes usando un árbol:
Analizar en árbol en base a los 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] 

Convertir el árbol de análisis en una expresión regular produce:

 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 

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

Si bien podrías hacerlo con una expresión regular de aspecto absurdo (como respondió VonC), se supone que Regex no debe hacer esto … ¿Por qué no posponer la verificación de número para redirigir a la secuencia de comandos?

Si los números 110-2234 van a script1, y 1-109 van a script2, sería mucho más simple dirigir todos los números a un script de router y hacer que lo redirijan a la ubicación correcta (a través de redireccionamientos HTTP).

En .htaccess :

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

..then en router.php , algo así como:

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

Es posible que no sea bonito.

 \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 electrónico a Phillip Hazel, el autor de PCRE, en 2006 sobre lo que pensaba de las matemáticas en expresiones regulares:

Tal vez esto quede fuera del scope del proyecto en su opinión: la capacidad de tratar los números como números y no como texto, definitivamente sería una característica que vale la pena. Permitiéndole hacer algunos controles matemáticos básicos en los dígitos coincidentes, como: ¿el segundo dígito coincidente es más alto o más bajo, el tercer dígito es un múltiplo del primero, y muchos casos más complicados que no detallaré para obtener mi punto al otro lado . ¿Sientes que esto excede el ámbito de la combinación de textos?

a lo que obtuve la siguiente respuesta:

Sí, creo que sí, y también, no es algo que esté disponible en las expresiones regulares de Perl. Sé que PCRE tiene algunas extensiones de Perl, pero nada tan importante como eso (tal vez puedas hackear algo utilizando rótulos, pero eso sería un poco ad hoc, ¡y sin duda demasiado complicado!).

Felipe

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.

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 

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]) 

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