Pregunta Javascript regex devuelve verdadero ... luego falso ... luego verdadero ... etc [duplicado]


Esta pregunta ya tiene una respuesta aquí:

Tengo un problema extraño con la validación que estoy escribiendo en un formulario. Es un botón 'Comprobar nombre de usuario' al lado de una entrada. El valor predeterminado de entrada es el nombre de usuario, por ejemplo, 'betamax'. Cuando presiono 'Comprobar nombre de usuario' pasa la expresión regular y envía el nombre de usuario al servidor. El servidor se comporta como se esperaba y devuelve '2' para indicar a los javascript que están enviando su propio nombre de usuario.

Luego, cuando hago clic en el botón nuevamente, la expresión regular falla. No se envía nada al servidor obviamente porque la expresión regular ha fallado. Si presiono el botón nuevamente, la expresión regular pasa y luego el nombre de usuario se envía al servidor.

¡Literalmente no puedo entender lo que lo haría hacer esto! ¡No tiene sentido para mí!

Editar: He probado el problema en Firefox y Chrome (mac)

Este es mi código:

$j("#username-search").click(checkUserName);

function checkUserName() {
    var userName = $j("#username").val();


    var invalidUserMsg = 'Invalid username (a-zA-Z0-9 _ - and not - or _ at beginning or end of string)';
    var filter = /^[^-_]([a-z0-9-_]{4,20})[^-_]$/gi;
    if (filter.test(userName)) {
        console.log("Pass")
        $j.post(
        "/account/profile/username_check/", 
        { q: userName }, 
        function(data){
            if(data == 0) {
                $j("#username-search-results").html("Error searching for username. Try again?");
            }
            else if(data == 5) {
                $j("#username-search-results").html(invalidUserMsg);
            }
            else if(data == 4) {
                $j("#username-search-results").html("Username too short or too long.");
            }
            else if(data == 2) {
                $j("#username-search-results").html("This is already your username.");
            }
            else if(data == 3) {
                $j("#username-search-results").html("This username is taken.");
            }
            else if(data == 1){
                $j("#username-search-results").html("This username is available!");
            }
        });
    } else {
        console.log("fail")
        $j("#username-search-results").html(invalidUserMsg);
    }

    return false;

}

El HTML:

<input name="username" id="username" value="{{ user.username }}" />
<input type="button" value="Is it taken?" id="username-search">
<span id="username-search-results"></span>

76
2018-04-13 14:40


origen


Respuestas:


/^[^-_]([a-z0-9-_]{4,20})[^-_]$/gi;

Estás usando un g (global) RegExp. En JavaScript, las expresiones regulares globales tienen estado: las llamas (con exec, test etc.) la primera vez, obtienes la primera coincidencia en una cadena dada. Llámalos de nuevo y obtendrás el próximo partido, y así sucesivamente hasta que no obtengas ninguna coincidencia y se restablezca al comienzo de la siguiente cadena. También puedes escribir regex.lastIndex= 0 para restablecer este estado.

(Esto es, por supuesto, una pieza absolutamente terrible de diseño, que confunde y causa errores extraños. ¡Bienvenido a JavaScript!)

Puedes omitir el g de tu RegExp, ya que solo estás probando un partido.

Además, no creo que quieras [^-_] en la parte delantera y trasera. Eso permitirá alguna carácter en cada extremo, es decir. *plop! sería válido Probablemente estés pensando en las afirmaciones de mirar hacia adelante / mirar hacia atrás, pero no están disponibles en JavaScript. (Bueno, se supone que debe ser anticipado, pero está roto en IE). Sugiera en su lugar:

/^[a-z0-9][a-z0-9_-]{2,18}[a-z0-9]$/i

140
2018-04-13 14:54



[a-z0-9-_]

Esto está mal, el último - debe estar al principio o al final.

[a-z0-9_-]

Si eso causaría o no este problema, no lo sé.

Notas adicionales:

El primer y el último caracteres pueden ser cualquier carácter que no sea - o _ en lugar de estar restringido a a-z0-9

a-z0-9 no incluye caracteres en mayúsculas Necesitas a-zA-Z0-9 para eso. a-zA-Z0-9_ puede acortarse a \w en la mayoría de los motores RegEx. No lo he probado en JavaScript.


2
2018-04-13 14:44