solo regulares regular rango que probar para online numeros nombres mayores hexadecimal expresiones expresion ejemplos regex math

regex - rango - probar expresiones regulares



Verifique la divisibilidad de los nĂºmeros con expresiones regulares (6)

Dado un número decimal N como una cadena de dígitos, ¿cómo verifico si es divisible por M usando solo expresiones regulares , sin convertir a int?

M = 2, 4, 5, 10 son obvios. Para M = 3 algunas ideas interesantes aquí: Regex números de filtro divisibles por 3

¿Alguien puede proporcionar una solución para M = 7, 9, 11, 13, etc.? ¿Una genérica?

Código de prueba (en python, pero puede usar cualquier idioma):

M = your number, e.g. 2 R = your regexp, e.g., ''^[0-9]*[02468]$'' import re for i in range(1, 2000): m = re.match(R, str(i)) if i % M: assert not m, ''%d should not match'' % i else: assert m, ''%d must match'' % i

Para aquellos curiosos, aquí hay un ejemplo para M=3 (asume un motor con soporte de recursión):

^ ( | [0369]+ (?1) | [147] (?1) [258] (?1) | [258] (?1) [147] (?1) | ( [258] (?1) ) {3} | ( [147] (?1) ) {3} ) $

Actualizaciones: para más discusión y ejemplos ver este thread . La expresión publicada allí resultó ser buggy (falla en 70 * N), pero la parte de "cómo llegar allí" es muy educativa.


Aquí hay una división genérica de la fuerza bruta recursiva recta genérica. No está optimizado y definitivamente no es elegante lol. Está en JavaScript (a continuación se muestra una página html de prueba con el código):

<!doctype html> <html> <head> <script type="text/javascript"> function isNDivisibleByM(N, M) { var copyN = N; var MLength = (""+M).length; var multiples = []; for(var x = 0; x < M; x++) multiples[x] = []; for(var i = M, x=0; i < M*10; x=0) { for(var j = i; j < i+M; j++, x++) multiples[x].push(j); i+=M; } var REs = []; for(var x = 0; x < M; x++) REs[x] = new RegExp("^("+multiples[x].join("|")+")"); while(N.length >= MLength) { var sameLen = (N.length == MLength); for(var x = 0; x < M; x++) N = N.replace(REs[x], (x==0)?"":(""+x)); N = N.replace(/^0/g, ""); if(sameLen) break; } N = N.replace(/^0/g, ""); var numericN = parseInt(copyN); if(N.length == 0) { if(numericN%M!=0) { console.error("Wrong claim: " + copyN + " NOT divisible by " + M); } return true; } if(numericN%M==0 && N.length != 0) { console.error("Missed claim: " + copyN + " IS divisible by " + M + " - " + N + " is: " + copyN); } return false; } function run() { alert(isNDivisibleByM((""+document.getElementById("N").value), parseInt(document.getElementById("M").value))); } </script> </head> <body> <label>N:</label><input type="text" id="N" /> <label>M:</label><input type="text" id="M" /> <button onclick="run()">Is N divisible by M?</button> </body> </html>

La idea es para M = 7 (ejemplo):

while(numStr.length > 1) { numStr = numStr.replace(/^(14|21|35|42|56|63)/, ""); numStr = numStr.replace(/^(15|22|36|43|50|64)/, "1"); numStr = numStr.replace(/^(16|23|30|44|51|65)/, "2"); numStr = numStr.replace(/^(10|24|31|45|52|66)/, "3"); numStr = numStr.replace(/^(11|25|32|46|53|60)/, "4"); numStr = numStr.replace(/^(12|26|33|40|54|61)/, "5"); numStr = numStr.replace(/^(13|20|34|41|55|62)/, "6"); }


El resultado quizás sorprendente es que tal expresión regular siempre existe. Lo menos sorprendente es que generalmente no es útil.

El resultado de la existencia proviene de la correspondencia entre autómatas finitos deterministas (DFA) y expresiones regulares. Así que vamos a hacer un DFA. Indica el módulo por N (no necesita ser primo) e indica la base numérica por B, que es 10 para los números decimales ordinarios. El DFA con N estados etiquetados de 0 a N-1. El estado inicial es 0. Los símbolos del DFA son los dígitos 0 a B-1. Los estados representan el resto del prefijo izquierdo de la cadena de entrada, interpretado como un entero, cuando se divide por N. Los bordes representan el cambio de estado cuando agrega un dígito a la derecha. Aritméticamente, este es el mapa de estado S (estado, dígito) = B * estado + dígito (módulo N). El estado de aceptación es 0, ya que un resto de cero indica divisibilidad. Así que tenemos un DFA. Los idiomas reconocidos por el DFA son los mismos que reconocen las expresiones regulares, por lo que existe uno. Entonces, si bien esto es interesante, no es útil, ya que no te dice mucho sobre cómo determinar la expresión.

Si desea un algoritmo genérico, es fácil crear un DFA de este tipo en tiempo de ejecución y rellenar su tabla de estado mediante cálculo directo. La inicialización es solo un par de bucles anidados con tiempo de ejecución O (M * N). El reconocimiento con la máquina es un tiempo constante por carácter de entrada. Esto es perfectamente rápido, pero no usa una biblioteca de expresiones regulares, si eso es lo que realmente necesita.

Para llegar a una expresión regular real, necesitamos observar el pequeño teorema de Fermat . Del teorema, sabemos que B ^ (N-1) == 1 (módulo N). Por ejemplo, cuando N = 7 y B = 10, lo que esto significa es que cada bloque de 6 dígitos es equivalente a algún dígito en el rango 0 .. 6 con el propósito de la divisibilidad. El exponente puede ser menor que N-1; en general, es un factor de la función totient de Euler de N. Llame al tamaño del bloque D. Hay N expresiones regulares para bloques de dígitos D, cada uno de los cuales representa una clase de equivalencia particular de restos módulo N. En la mayoría, estas expresiones tienen longitud O (B ^ D), que es grande. Para N = 7 es un conjunto de expresiones regulares de un millón de caracteres; Me imagino que rompería la mayoría de las bibliotecas de expresiones regulares.

Esto se relaciona con cómo funciona la expresión en el código de ejemplo; la expresión (?1) corresponde a cadenas que son iguales a 0 (mod 3). Esto funciona con N = 3 desde 10 ^ 1 == 1 (mod 3), lo que significa que A0B == AB (mod 3). Esto es más complicado cuando el exponente es mayor que 1, pero el principio es el mismo. (Tenga en cuenta que el código de ejemplo utiliza un reconocedor que es más que simples expresiones regulares, estrictamente hablando). Las expresiones [0369] , [147] y [258] son las expresiones regulares para los dígitos 0, 1 y 2 en una modulo 3 expresion Generalizando, usaría los números de expresión regular como los anteriores de una manera análoga.

No estoy proporcionando el código porque (1) tardaría más en escribir que esta respuesta, y (2) realmente dudo que se ejecutaría en cualquier implementación conocida.


Esta es una pregunta antigua, pero ninguna de las respuestas existentes incluye código. Escribí un código para calcular estas expresiones regulares en 2010, que está en línea aquí y tiene un enlace al código fuente comentado , por lo que pensé que podría ser útil agregar un enlace aquí.

La técnica es básicamente la descrita en la respuesta de eh9 , excepto que calculo una expresión regular directamente desde el DFA utilizando la eliminación de estado y luego aplico algunas simplificaciones al resultado. Son simples expresiones regulares, sin recursión. (El uso de la recursión haría que los resultados fueran mucho más cortos, pero creo que es interesante que no sea posible).

Los resultados no son tan detallados como lo sugiere la estimación de eh9. Por ejemplo, aquí hay una expresión regular que coincide con múltiplos de 7 en la base 10:

^(0|7|[18]5*4|(2|9|[18]5*6)(3|[29]5*6)*(1|8|[29]5*4)|(3|[18]5*[07]|(2|9|[18]5*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(5|65*4|(0|7|65*6)(3|[29]5*6)*(1|8|[29]5*4))|(4|[18]5*[18]|(2|9|[18]5*6)(3|[29]5*6)*(5|[29]5*[18])|(3|[18]5*[07]|(2|9|[18]5*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(2|9|65*[18]|(0|7|65*6)(3|[29]5*6)*(5|[29]5*[18])))(6|35*[18]|(4|35*6)(3|[29]5*6)*(5|[29]5*[18])|(5|35*[07]|(4|35*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(2|9|65*[18]|(0|7|65*6)(3|[29]5*6)*(5|[29]5*[18])))*(2|9|35*4|(4|35*6)(3|[29]5*6)*(1|8|[29]5*4)|(5|35*[07]|(4|35*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(5|65*4|(0|7|65*6)(3|[29]5*6)*(1|8|[29]5*4)))|(5|[18]5*[29]|(2|9|[18]5*6)(3|[29]5*6)*(6|[29]5*[29])|(3|[18]5*[07]|(2|9|[18]5*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(3|65*[29]|(0|7|65*6)(3|[29]5*6)*(6|[29]5*[29]))|(4|[18]5*[18]|(2|9|[18]5*6)(3|[29]5*6)*(5|[29]5*[18])|(3|[18]5*[07]|(2|9|[18]5*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(2|9|65*[18]|(0|7|65*6)(3|[29]5*6)*(5|[29]5*[18])))(6|35*[18]|(4|35*6)(3|[29]5*6)*(5|[29]5*[18])|(5|35*[07]|(4|35*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(2|9|65*[18]|(0|7|65*6)(3|[29]5*6)*(5|[29]5*[18])))*(0|7|35*[29]|(4|35*6)(3|[29]5*6)*(6|[29]5*[29])|(5|35*[07]|(4|35*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(3|65*[29]|(0|7|65*6)(3|[29]5*6)*(6|[29]5*[29]))))(4|[07]5*[29]|(1|8|[07]5*6)(3|[29]5*6)*(6|[29]5*[29])|(2|9|[07]5*[07]|(1|8|[07]5*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(3|65*[29]|(0|7|65*6)(3|[29]5*6)*(6|[29]5*[29]))|(3|[07]5*[18]|(1|8|[07]5*6)(3|[29]5*6)*(5|[29]5*[18])|(2|9|[07]5*[07]|(1|8|[07]5*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(2|9|65*[18]|(0|7|65*6)(3|[29]5*6)*(5|[29]5*[18])))(6|35*[18]|(4|35*6)(3|[29]5*6)*(5|[29]5*[18])|(5|35*[07]|(4|35*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(2|9|65*[18]|(0|7|65*6)(3|[29]5*6)*(5|[29]5*[18])))*(0|7|35*[29]|(4|35*6)(3|[29]5*6)*(6|[29]5*[29])|(5|35*[07]|(4|35*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(3|65*[29]|(0|7|65*6)(3|[29]5*6)*(6|[29]5*[29]))))*(6|[07]5*4|(1|8|[07]5*6)(3|[29]5*6)*(1|8|[29]5*4)|(2|9|[07]5*[07]|(1|8|[07]5*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(5|65*4|(0|7|65*6)(3|[29]5*6)*(1|8|[29]5*4))|(3|[07]5*[18]|(1|8|[07]5*6)(3|[29]5*6)*(5|[29]5*[18])|(2|9|[07]5*[07]|(1|8|[07]5*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(2|9|65*[18]|(0|7|65*6)(3|[29]5*6)*(5|[29]5*[18])))(6|35*[18]|(4|35*6)(3|[29]5*6)*(5|[29]5*[18])|(5|35*[07]|(4|35*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(2|9|65*[18]|(0|7|65*6)(3|[29]5*6)*(5|[29]5*[18])))*(2|9|35*4|(4|35*6)(3|[29]5*6)*(1|8|[29]5*4)|(5|35*[07]|(4|35*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(5|65*4|(0|7|65*6)(3|[29]5*6)*(1|8|[29]5*4))))|(6|[18]5*3|(2|9|[18]5*6)(3|[29]5*6)*(0|7|[29]5*3)|(3|[18]5*[07]|(2|9|[18]5*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(4|65*3|(0|7|65*6)(3|[29]5*6)*(0|7|[29]5*3))|(4|[18]5*[18]|(2|9|[18]5*6)(3|[29]5*6)*(5|[29]5*[18])|(3|[18]5*[07]|(2|9|[18]5*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(2|9|65*[18]|(0|7|65*6)(3|[29]5*6)*(5|[29]5*[18])))(6|35*[18]|(4|35*6)(3|[29]5*6)*(5|[29]5*[18])|(5|35*[07]|(4|35*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(2|9|65*[18]|(0|7|65*6)(3|[29]5*6)*(5|[29]5*[18])))*(1|8|35*3|(4|35*6)(3|[29]5*6)*(0|7|[29]5*3)|(5|35*[07]|(4|35*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(4|65*3|(0|7|65*6)(3|[29]5*6)*(0|7|[29]5*3)))|(5|[18]5*[29]|(2|9|[18]5*6)(3|[29]5*6)*(6|[29]5*[29])|(3|[18]5*[07]|(2|9|[18]5*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(3|65*[29]|(0|7|65*6)(3|[29]5*6)*(6|[29]5*[29]))|(4|[18]5*[18]|(2|9|[18]5*6)(3|[29]5*6)*(5|[29]5*[18])|(3|[18]5*[07]|(2|9|[18]5*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(2|9|65*[18]|(0|7|65*6)(3|[29]5*6)*(5|[29]5*[18])))(6|35*[18]|(4|35*6)(3|[29]5*6)*(5|[29]5*[18])|(5|35*[07]|(4|35*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(2|9|65*[18]|(0|7|65*6)(3|[29]5*6)*(5|[29]5*[18])))*(0|7|35*[29]|(4|35*6)(3|[29]5*6)*(6|[29]5*[29])|(5|35*[07]|(4|35*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(3|65*[29]|(0|7|65*6)(3|[29]5*6)*(6|[29]5*[29]))))(4|[07]5*[29]|(1|8|[07]5*6)(3|[29]5*6)*(6|[29]5*[29])|(2|9|[07]5*[07]|(1|8|[07]5*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(3|65*[29]|(0|7|65*6)(3|[29]5*6)*(6|[29]5*[29]))|(3|[07]5*[18]|(1|8|[07]5*6)(3|[29]5*6)*(5|[29]5*[18])|(2|9|[07]5*[07]|(1|8|[07]5*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(2|9|65*[18]|(0|7|65*6)(3|[29]5*6)*(5|[29]5*[18])))(6|35*[18]|(4|35*6)(3|[29]5*6)*(5|[29]5*[18])|(5|35*[07]|(4|35*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(2|9|65*[18]|(0|7|65*6)(3|[29]5*6)*(5|[29]5*[18])))*(0|7|35*[29]|(4|35*6)(3|[29]5*6)*(6|[29]5*[29])|(5|35*[07]|(4|35*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(3|65*[29]|(0|7|65*6)(3|[29]5*6)*(6|[29]5*[29]))))*(5|[07]5*3|(1|8|[07]5*6)(3|[29]5*6)*(0|7|[29]5*3)|(2|9|[07]5*[07]|(1|8|[07]5*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(4|65*3|(0|7|65*6)(3|[29]5*6)*(0|7|[29]5*3))|(3|[07]5*[18]|(1|8|[07]5*6)(3|[29]5*6)*(5|[29]5*[18])|(2|9|[07]5*[07]|(1|8|[07]5*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(2|9|65*[18]|(0|7|65*6)(3|[29]5*6)*(5|[29]5*[18])))(6|35*[18]|(4|35*6)(3|[29]5*6)*(5|[29]5*[18])|(5|35*[07]|(4|35*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(2|9|65*[18]|(0|7|65*6)(3|[29]5*6)*(5|[29]5*[18])))*(1|8|35*3|(4|35*6)(3|[29]5*6)*(0|7|[29]5*3)|(5|35*[07]|(4|35*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(4|65*3|(0|7|65*6)(3|[29]5*6)*(0|7|[29]5*3)))))(2|9|45*3|(5|45*6)(3|[29]5*6)*(0|7|[29]5*3)|(6|45*[07]|(5|45*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(4|65*3|(0|7|65*6)(3|[29]5*6)*(0|7|[29]5*3))|(0|7|45*[18]|(5|45*6)(3|[29]5*6)*(5|[29]5*[18])|(6|45*[07]|(5|45*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(2|9|65*[18]|(0|7|65*6)(3|[29]5*6)*(5|[29]5*[18])))(6|35*[18]|(4|35*6)(3|[29]5*6)*(5|[29]5*[18])|(5|35*[07]|(4|35*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(2|9|65*[18]|(0|7|65*6)(3|[29]5*6)*(5|[29]5*[18])))*(1|8|35*3|(4|35*6)(3|[29]5*6)*(0|7|[29]5*3)|(5|35*[07]|(4|35*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(4|65*3|(0|7|65*6)(3|[29]5*6)*(0|7|[29]5*3)))|(1|8|45*[29]|(5|45*6)(3|[29]5*6)*(6|[29]5*[29])|(6|45*[07]|(5|45*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(3|65*[29]|(0|7|65*6)(3|[29]5*6)*(6|[29]5*[29]))|(0|7|45*[18]|(5|45*6)(3|[29]5*6)*(5|[29]5*[18])|(6|45*[07]|(5|45*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(2|9|65*[18]|(0|7|65*6)(3|[29]5*6)*(5|[29]5*[18])))(6|35*[18]|(4|35*6)(3|[29]5*6)*(5|[29]5*[18])|(5|35*[07]|(4|35*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(2|9|65*[18]|(0|7|65*6)(3|[29]5*6)*(5|[29]5*[18])))*(0|7|35*[29]|(4|35*6)(3|[29]5*6)*(6|[29]5*[29])|(5|35*[07]|(4|35*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(3|65*[29]|(0|7|65*6)(3|[29]5*6)*(6|[29]5*[29]))))(4|[07]5*[29]|(1|8|[07]5*6)(3|[29]5*6)*(6|[29]5*[29])|(2|9|[07]5*[07]|(1|8|[07]5*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(3|65*[29]|(0|7|65*6)(3|[29]5*6)*(6|[29]5*[29]))|(3|[07]5*[18]|(1|8|[07]5*6)(3|[29]5*6)*(5|[29]5*[18])|(2|9|[07]5*[07]|(1|8|[07]5*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(2|9|65*[18]|(0|7|65*6)(3|[29]5*6)*(5|[29]5*[18])))(6|35*[18]|(4|35*6)(3|[29]5*6)*(5|[29]5*[18])|(5|35*[07]|(4|35*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(2|9|65*[18]|(0|7|65*6)(3|[29]5*6)*(5|[29]5*[18])))*(0|7|35*[29]|(4|35*6)(3|[29]5*6)*(6|[29]5*[29])|(5|35*[07]|(4|35*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(3|65*[29]|(0|7|65*6)(3|[29]5*6)*(6|[29]5*[29]))))*(5|[07]5*3|(1|8|[07]5*6)(3|[29]5*6)*(0|7|[29]5*3)|(2|9|[07]5*[07]|(1|8|[07]5*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(4|65*3|(0|7|65*6)(3|[29]5*6)*(0|7|[29]5*3))|(3|[07]5*[18]|(1|8|[07]5*6)(3|[29]5*6)*(5|[29]5*[18])|(2|9|[07]5*[07]|(1|8|[07]5*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(2|9|65*[18]|(0|7|65*6)(3|[29]5*6)*(5|[29]5*[18])))(6|35*[18]|(4|35*6)(3|[29]5*6)*(5|[29]5*[18])|(5|35*[07]|(4|35*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(2|9|65*[18]|(0|7|65*6)(3|[29]5*6)*(5|[29]5*[18])))*(1|8|35*3|(4|35*6)(3|[29]5*6)*(0|7|[29]5*3)|(5|35*[07]|(4|35*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(4|65*3|(0|7|65*6)(3|[29]5*6)*(0|7|[29]5*3)))))*(3|45*4|(5|45*6)(3|[29]5*6)*(1|8|[29]5*4)|(6|45*[07]|(5|45*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(5|65*4|(0|7|65*6)(3|[29]5*6)*(1|8|[29]5*4))|(0|7|45*[18]|(5|45*6)(3|[29]5*6)*(5|[29]5*[18])|(6|45*[07]|(5|45*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(2|9|65*[18]|(0|7|65*6)(3|[29]5*6)*(5|[29]5*[18])))(6|35*[18]|(4|35*6)(3|[29]5*6)*(5|[29]5*[18])|(5|35*[07]|(4|35*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(2|9|65*[18]|(0|7|65*6)(3|[29]5*6)*(5|[29]5*[18])))*(2|9|35*4|(4|35*6)(3|[29]5*6)*(1|8|[29]5*4)|(5|35*[07]|(4|35*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(5|65*4|(0|7|65*6)(3|[29]5*6)*(1|8|[29]5*4)))|(1|8|45*[29]|(5|45*6)(3|[29]5*6)*(6|[29]5*[29])|(6|45*[07]|(5|45*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(3|65*[29]|(0|7|65*6)(3|[29]5*6)*(6|[29]5*[29]))|(0|7|45*[18]|(5|45*6)(3|[29]5*6)*(5|[29]5*[18])|(6|45*[07]|(5|45*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(2|9|65*[18]|(0|7|65*6)(3|[29]5*6)*(5|[29]5*[18])))(6|35*[18]|(4|35*6)(3|[29]5*6)*(5|[29]5*[18])|(5|35*[07]|(4|35*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(2|9|65*[18]|(0|7|65*6)(3|[29]5*6)*(5|[29]5*[18])))*(0|7|35*[29]|(4|35*6)(3|[29]5*6)*(6|[29]5*[29])|(5|35*[07]|(4|35*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(3|65*[29]|(0|7|65*6)(3|[29]5*6)*(6|[29]5*[29]))))(4|[07]5*[29]|(1|8|[07]5*6)(3|[29]5*6)*(6|[29]5*[29])|(2|9|[07]5*[07]|(1|8|[07]5*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(3|65*[29]|(0|7|65*6)(3|[29]5*6)*(6|[29]5*[29]))|(3|[07]5*[18]|(1|8|[07]5*6)(3|[29]5*6)*(5|[29]5*[18])|(2|9|[07]5*[07]|(1|8|[07]5*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(2|9|65*[18]|(0|7|65*6)(3|[29]5*6)*(5|[29]5*[18])))(6|35*[18]|(4|35*6)(3|[29]5*6)*(5|[29]5*[18])|(5|35*[07]|(4|35*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(2|9|65*[18]|(0|7|65*6)(3|[29]5*6)*(5|[29]5*[18])))*(0|7|35*[29]|(4|35*6)(3|[29]5*6)*(6|[29]5*[29])|(5|35*[07]|(4|35*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(3|65*[29]|(0|7|65*6)(3|[29]5*6)*(6|[29]5*[29]))))*(6|[07]5*4|(1|8|[07]5*6)(3|[29]5*6)*(1|8|[29]5*4)|(2|9|[07]5*[07]|(1|8|[07]5*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(5|65*4|(0|7|65*6)(3|[29]5*6)*(1|8|[29]5*4))|(3|[07]5*[18]|(1|8|[07]5*6)(3|[29]5*6)*(5|[29]5*[18])|(2|9|[07]5*[07]|(1|8|[07]5*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(2|9|65*[18]|(0|7|65*6)(3|[29]5*6)*(5|[29]5*[18])))(6|35*[18]|(4|35*6)(3|[29]5*6)*(5|[29]5*[18])|(5|35*[07]|(4|35*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(2|9|65*[18]|(0|7|65*6)(3|[29]5*6)*(5|[29]5*[18])))*(2|9|35*4|(4|35*6)(3|[29]5*6)*(1|8|[29]5*4)|(5|35*[07]|(4|35*6)(3|[29]5*6)*(4|[29]5*[07]))(1|8|65*[07]|(0|7|65*6)(3|[29]5*6)*(4|[29]5*[07]))*(5|65*4|(0|7|65*6)(3|[29]5*6)*(1|8|[29]5*4))))))*$

que es "solo" 12,733 caracteres y funciona bien en las implementaciones que he probado.

PD. Para ver cuánto menos interesante es el uso de recursión, aquí hay un programa Perl que prueba la divisibilidad mediante 7 usando una expresión regular recursiva:

my $re = qr{ ^($|[07](?1)|[18](?2)|[29](?3)|3(?4)|4(?5)|5(?6)|6(?7)) |(?!)(?: ([07](?4)|[18](?5)|[29](?6)|3(?7)|4(?1)|5(?2)|6(?3)) | ([07](?7)|[18](?1)|[29](?2)|3(?3)|4(?4)|5(?5)|6(?6)) | ([07](?3)|[18](?4)|[29](?5)|3(?6)|4(?7)|5(?1)|6(?2)) | ([07](?6)|[18](?7)|[29](?1)|3(?2)|4(?3)|5(?4)|6(?5)) | ([07](?2)|[18](?3)|[29](?4)|3(?5)|4(?6)|5(?7)|6(?1)) | ([07](?5)|[18](?6)|[29](?7)|3(?1)|4(?2)|5(?3)|6(?4)) ) }x; while (<>) { print(/$re/ ? "matches/n" : "does not match/n"); }

Esta es solo una expresión directa de la DFA como una expresión regular recursiva.


Por muy interesante que sea esta pregunta, no creo que sea posible para otra cosa que no sean las "obvias" que enumera.

La mayoría de las reglas de divisibilidad requieren manipulación matemática.

Puede usar un lookahead para probar la cadena para más de un requisito , de modo que pueda combinar pares de los "obvios" (2 x 3, 3 x 5, etc.):

Unir una palabra de 6 letras es fácil con /b/w{6}/b . Igualar una palabra que contenga "cat" es igual de fácil: /b/w*cat/w*/b .

Combinando los dos, obtenemos: (?=/b/w{6}/b)/b/w*cat/w*/b Analiza esta expresión regular con RegexBuddy. ¡Fácil! Así es como funciona esto. En cada posición de carácter en la cadena donde se intenta la expresión regular, el motor intentará primero la expresión regular dentro del lookahead positivo. Este sub-regex, y por lo tanto el lookahead, coincide solo cuando la posición actual del carácter en la cadena está al comienzo de una palabra de 6 letras en la cadena. Si no, el lookahead fallará, y el motor continuará intentando la expresión regular desde el inicio en la siguiente posición de carácter en la cadena.


Si se le permite modificar la cadena y repetir, puede hacer un paso de división larga a la vez. sintaxis sed para 7: vuelva a aplicar hasta que obtenga el resto. Deténgase cuando tenga un solo 0, 1, 2, 3, 4, 5 o 6.

s/^0// s/^7/0/ s/^8/1/ s/^9/2/ s/^([18]4|[29][18]|35|4[29]|56|63)/0/ s/^([18]5|[29][29]|36|43|5[07]|64)/1/ s/^([18]6|[29]3|3[07]|44|5[18]|65)/2/ s/^([18][07]|[29]4|3[18]|45|5[29]|66)/3/ s/^([18][18]|[29]5|3[29]|46|53|6[07])/4/ s/^([18][29]|[29]6|33|4[07]|54|6[18])/5/ s/^([18]3|[29][07]|34|4[18]|55|6[29])/6/

Pero es una salsa muy débil. Es más fácil eliminar el "regex" por completo y solo leer un personaje a la vez y cambiar al estado apropiado. Si esa no es una opción, entonces sospecho que estás fuera de suerte para 7 y 13, aunque 11 todavía podría ser posible.


Si sus números son únicos, puede usar esta expresión regular: s/1{divisor}//g luego verifique si el número está vacío.

Aquí hay una forma de Perl para hacerlo.

my @divs = (2,3,5,7,11,13); for my $num(2..26) { my $unary = ''1''x$num; # convert num to unary print "/n$num can be divided by : "; for(@divs) { my $test = $unary; $test =~ s/1{$_}//g; print "$_, " unless $test; } }

salida:

2 can be divided by : 2, 3 can be divided by : 3, 4 can be divided by : 2, 5 can be divided by : 5, 6 can be divided by : 2, 3, 7 can be divided by : 7, 8 can be divided by : 2, 9 can be divided by : 3, 10 can be divided by : 2, 5, 11 can be divided by : 11, 12 can be divided by : 2, 3, 13 can be divided by : 13, 14 can be divided by : 2, 7, 15 can be divided by : 3, 5, 16 can be divided by : 2, 17 can be divided by : 18 can be divided by : 2, 3, 19 can be divided by : 20 can be divided by : 2, 5, 21 can be divided by : 3, 7, 22 can be divided by : 2, 11, 23 can be divided by : 24 can be divided by : 2, 3, 25 can be divided by : 5, 26 can be divided by : 2, 13,