Frage Javascript-Regex, das wahr zurückgibt .. dann falsch .. dann wahr .. usw. [doppelt]


Diese Frage hat hier bereits eine Antwort:

Ich habe ein seltsames Problem mit der Validierung, die ich in einem Formular schreibe. Es ist eine Schaltfläche "Benutzernamen prüfen" neben einer Eingabe. Der eingegebene Standardwert ist der Benutzername, zum Beispiel 'betamax'. Wenn ich 'Check Username' drücke, übergibt es die Regex und sendet den Benutzernamen an den Server. Der Server verhält sich wie erwartet und gibt '2' zurück, um dem Javascript mitzuteilen, dass sie ihren eigenen Benutzernamen eingeben.

Wenn ich dann erneut auf die Schaltfläche klicke, schlägt die Regex fehl. Nichts wird offensichtlich zum Server gesendet, weil die Regex fehlgeschlagen ist. Wenn ich die Taste erneut drücke, wird die Regex übergeben und der Benutzername wird an den Server gesendet.

Ich kann buchstäblich nicht herausfinden, was es dazu bringen würde! Es ergibt keinen Sinn für mich!

Edit: Ich habe das Problem in Firefox und Chrome (Mac) getestet

Das ist mein Code:

$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;

}

Der 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


Ursprung


Antworten:


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

Du benutzt ein g (global) RegExp. In JavaScript haben globale Regexen Status: Sie rufen sie (mit exec, test usw.) Beim ersten Mal erhalten Sie die erste Übereinstimmung in einer gegebenen Zeichenfolge. Rufen Sie sie erneut an, und Sie erhalten die nächste Übereinstimmung und so weiter, bis Sie keine Übereinstimmung mehr erhalten und sie auf den Anfang der nächsten Zeichenfolge zurückgesetzt wird. Sie können auch schreiben regex.lastIndex= 0 um diesen Zustand zurückzusetzen.

(Dies ist natürlich ein absolut schreckliches Stück Design, garantiert zu verwirren und seltsame Fehler zu verursachen. Willkommen in JavaScript!)

Sie können das weglassen g von deiner RegExp, da du nur für ein Spiel testest.

Außerdem glaube ich nicht, dass du willst [^-_] vorne und hinten. Das wird erlauben irgendein Zeichen an jedem Ende, dh. *plop! wäre gültig. Sie denken wahrscheinlich an Lookahead / Lookbehind-Assertionen, aber diese sind in JavaScript nicht verfügbar. (Nun, Lookahead sollte sein, aber es ist in IE gebrochen.) Stattdessen vorschlagen:

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

140
2018-04-13 14:54



[a-z0-9-_]

Das ist falsch, das letzte - muss am Anfang oder am Ende sein.

[a-z0-9_-]

Ob das das Problem verursachen würde oder nicht, weiß ich nicht.

Zusätzliche Bemerkungen:

Das erste und letzte Zeichen darf ein beliebiges Zeichen sein - oder _ anstatt beschränkt zu sein a-z0-9

a-z0-9 enthält keine Großbuchstaben. Du brauchst a-zA-Z0-9 dafür. a-zA-Z0-9_ kann verkürzt werden \w in den meisten RegEx-Engines. Ich habe es nicht in JavaScript versucht.


2
2018-04-13 14:44