Considere la siguiente expresión regular, donde X
es cualquier expresión regular.
X{n}|X{m}
Esta expresión regular probaría que X
ocurra exactamente n
o m
veces.
¿Existe un cuantificador de expresiones regulares que pueda probar una ocurrencia X
exactamente n
o m
veces?
X
es el mejor que se puede obtener de forma en generalm
,n
.(X)\1{n-1}(?:\1{m-n-1})
. Sé que esto coincideX
al menos una vez, pero solo para comenzar, pruebe esto simple y luego refine usando lookaheads o lookbehinds en lugar de(X)
.Respuestas:
No existe un cuantificador único que signifique "exactamente m o n veces". La forma en que lo estás haciendo está bien.
Una alternativa es:
donde
m < n
yk
es el valor den-m
.fuente
Aquí está la lista completa de cuantificadores (ref. Http://www.regular-expressions.info/reference.html ):
?
,??
- 0 o 1 ocurrencias (??
es perezoso,?
es codicioso)*
,*?
- cualquier número de ocurrencias+
,+?
- al menos una ocurrencia{n}
-n
ocurrencias exactas{n,m}
-n
am
ocurrencias, inclusive{n,m}?
-n
a lasm
ocurrencias, perezoso{n,}
,{n,}?
- al menosn
ocurrenciaPara obtener "exactamente N o M", debe escribir la expresión regular cuantificada dos veces, a menos que m, n sean especiales:
X{n,m}
Sim = n+1
(?:X{n}){1,2}
Sim = 2n
fuente
?:
necesario en elm = 2n
ejemplo if ? Parece funcionar bien sin él para mí.?:
, el grupo se convierte en un grupo de captura. Aparte de que el motor de expresiones regulares recuerda cosas que no tiene por qué, si tiene grupos de captura después de este, sus ID cambiarán. Si usa su expresión regular para la sustitución, tendrá que ajustar el reemplazo.No, no existe tal cuantificador. Pero lo reestructuraría
/X{m}(X{m-n})?/
para evitar problemas al dar marcha atrás .fuente
TLDR;
(?<=[^x]|^)(x{n}|x{m})(?:[^x]|$)
Parece que quieres "xn veces" o "xm veces", creo que una traducción literal a regex sería
(x{n}|x{m}).
como esta https://regex101.com/r/vH7yL5/1o, en un caso en el que pueda tener una secuencia de más de m "x" s (suponiendo que m> n), puede agregar 'después de no "x"' y 'seguido de no "x", traduciendo a
[^x](x{n}|x{m})[^x]
pero eso sería suponga que siempre hay un carácter detrás y después de usted "x". Como puede ver aquí: https://regex101.com/r/bB2vH2/1puede cambiarlo a
(?:[^x]|^)(x{n}|x{m})(?:[^x]|$)
, que se traduce en "sin 'x' o siguiente inicio de línea" y "seguido de 'x' o final de línea". Pero aún así, no coincidirá con dos secuencias con un solo carácter entre ellas (porque la primera coincidencia requeriría un carácter después y la segunda un carácter antes) como puede ver aquí: https://regex101.com/r/ oC5oJ4 / 1Por último, para hacer coincidir la coincidencia distante de un carácter, puede agregar una mirada positiva hacia adelante (? =) En el "no 'x' después" o una mirada positiva detrás (? <=) En el "no 'x' antes", así: https://regex101.com/r/mC4uX3/1
De esta manera, coincidirá solo con el número exacto de 'x' que desee.
fuente
Echando un vistazo a la respuesta de Enhardened, afirman que su penúltima expresión no coincidirá con secuencias con un solo carácter entre ellas. Hay una manera fácil de solucionar este problema sin usar mirar hacia adelante / mirar atrás, y es reemplazar el carácter de inicio / fin con el carácter de límite. Esto le permite hacer coincidir los límites de las palabras que incluyen inicio / final. Como tal, la expresión apropiada debería ser:
(?:[^x]|\b)(x{n}|x{m})(?:[^x]|\b)
Como puede ver aquí: https://regex101.com/r/oC5oJ4/2 .
fuente
Publicación muy antigua, pero me gustaría contribuir con algo que pueda ser de ayuda. Lo probé exactamente de la manera indicada en la pregunta y funciona, pero hay un problema: el orden de las cantidades importa. Considera esto:
Esto encontrará todas las apariciones de códigos de color hexadecimales (tienen 3 o 6 dígitos). Pero cuando le doy la vuelta así
solo encontrará los de 3 dígitos o los primeros 3 dígitos de los de 6 dígitos. Esto tiene sentido y un profesional de Regex podría detectarlo de inmediato, pero para muchos esto podría ser un comportamiento peculiar. Hay algunas características avanzadas de Regex que pueden evitar esta trampa independientemente del orden, pero no todos están metidos hasta las rodillas en los patrones de Regex.
fuente