¿Por qué esta expresión regular permite un intercalado?

http://regexr.com/3ars8

^(?=.*[0-9])(?=.*[Az])[0-9A-z-]{17}$ 

Debe coincidir con “17 caracteres alfanuméricos, los guiones permitidos también deben incluir al menos una letra y al menos un número”.

Equivará correctamente:

 ABCDF31U100027743 

y declinar correctamente para que coincida:

 AB$DF31U100027743 

(y casi cualquier otro carácter no alfanumérico)

pero aparentemente permitirá:

 AB^DF31U100027743 

Porque tu clase de caracteres [Az] coincide con este símbolo.

[Az] coincide con [ , \ , ] , ^ , _ , ` y las letras en inglés.

En realidad, es un error común. Debería usar [a-zA-Z] lugar para permitir solo letras en inglés.

Aquí hay una visualización de Expresso, que muestra qué cubre realmente el rango [Az] :

captura de pantalla de Expresso que muestra la tabla ASCII, donde puede ver lo que cubre realmente el rango [A-z]

Por lo tanto, esta expresión regular (con la opción i ) no capturará su cadena.

 ^(?=.*[0-9])(?=.*[az])[0-9a-z-]{17}$ 

En mi opinión, siempre es más seguro usar la opción Ignorecase para evitar ese problema y acortar la expresión regular.

regex usa caracteres imprimibles ASCII desde el espacio hasta el rango de tilde.

Siempre que usemos token [Az] , coincide con la siguiente tabla de caracteres resaltados. Si usamos [ -~] token, coincide con el inicio de SPACE a tilde.

enter image description here

Está permitiendo Az (capital ‘A’ a través de ‘z’ inferior). No dice qué paquete de expresiones regulares está utilizando, pero no es necesariamente claro que AZ y az son contiguas; podría haber otros personajes en el medio. Pruebe esto en su lugar:

 ^(?=.*[0-9])(?=.*[A-Za-z])[0-9A-Za-z-]{17}$ 

Parece cumplir tus criterios para mí en regexpal.