Najlepszy sposób na alfanumeryczne sprawdzanie w Javascript


107

Jaki jest najlepszy sposób sprawdzenia alfanumerycznego INPUTpola w JSP? Załączam mój aktualny kod

<script type="text/javascript">
  function validateCode(){
      var TCode = document.getElementById('TCode').value;
      for(var i=0; i<TCode.length; i++)
      {
        var char1 = TCode.charAt(i);
        var cc = char1.charCodeAt(0);

        if((cc>47 && cc<58) || (cc>64 && cc<91) || (cc>96 && cc<123))
        {

        }
         else {
         alert('Input is not alphanumeric');
         return false;
         }
      }
     return true;     
   }


2
Zależy, jak zdefiniujesz „najlepsze”. Większość poniższych odpowiedzi sugeruje wyrażenie regularne, które działa znacznie wolniej niż oryginalny kod . Mam oczyścić swój kod bit, który faktycznie wykonuje bardzo dobrze.
Michael Martin-Smucker

Odpowiedzi:


100

Możesz użyć tego wyrażenia regularnego /^[a-z0-9]+$/i


4
oczywiście zakłada to, że pusty ciąg ( "") nie powinien być dopasowany.
zzzzBov

15
ñnie pasuje do wzorca, jednak w pełni poprawny znak UTF-8.
Oybek

8
/ ^ [a-z0-9] + $ / i.test (TCode)
Alex V

3
Testowanie wyrażenia regularnego wydaje się być znacznie wolniejsze (66% w Chrome 36) niż charCodeAt(). Zobacz jsPerf i moją odpowiedź poniżej .
Michael Martin-Smucker

5
To wyrażenie regularne nie działa ze specjalnymi literami znaków używanymi w niektórych językach, np. „Ą”, „ź”, „ć” itp.
Rafał Swacha

79

Oryginalna skłonność pytającego do użycia str.charCodeAt(i)wydaje się szybsza niż alternatywa wyrażenia regularnego. W moim teście na jsPerf opcja RegExp działa o 66% wolniej w przeglądarce Chrome 36 (i nieco wolniej w przeglądarce Firefox 31).

Oto oczyszczona wersja oryginalnego kodu walidacji, która otrzymuje ciąg znaków i zwraca truelub false:

function isAlphaNumeric(str) {
  var code, i, len;

  for (i = 0, len = str.length; i < len; i++) {
    code = str.charCodeAt(i);
    if (!(code > 47 && code < 58) && // numeric (0-9)
        !(code > 64 && code < 91) && // upper alpha (A-Z)
        !(code > 96 && code < 123)) { // lower alpha (a-z)
      return false;
    }
  }
  return true;
};

Oczywiście mogą istnieć inne względy, takie jak czytelność. Jednowierszowe wyrażenie regularne jest zdecydowanie ładniejsze. Ale jeśli zależy Ci wyłącznie na szybkości, możesz rozważyć tę alternatywę.


17
Programiści uwielbiają wygląd kodu, ale widzisz jego wewnętrzne piękno.
Ziggy,

Ciekawe alternatywne podejście - nawet nie przyszło mi do głowy. Przyszedłem tutaj z myślą tylko o wyrażeniu regularnym!
ozzy432836

Odpowiedź, która skłania do myślenia i pozwala zrozumieć, co to znaczy „programowanie”. Używam twojego sposobu myślenia w mojej odpowiedzi
Oscar Zarrus

42

Sprawdź to za pomocą wyrażenia regularnego.

Wyrażenia regularne Javascript nie mają klas znaków POSIX, więc musisz ręcznie pisać zakresy znaków:

if (!input_string.match(/^[0-9a-z]+$/))
  show_error_or_something()

Tutaj ^oznacza początek ciągu i $oznacza koniec ciągu i [0-9a-z]+oznacza jeden lub więcej znaków od 0do 9LUB od ado z.

Więcej informacji na temat wyrażeń regularnych Javascript tutaj: https://developer.mozilla.org/en/JavaScript/Guide/Regular_Expressions


14
+1 za wyjaśnienie podstawowego wyrażenia regularnego i linkowanie do przewodnika, zamiast dawania użytkownikowi „magicznego ciągu”.
Charles Burns

4
@inor możesz po prostu dodać `` i '' na końcu wyrażenia regularnego, aby określić niewrażliwość na wielkość liter, .ie, /^[a-z0-9]+$/ia to obejmie zarówno małe, jak i duże litery
LJH

33

Nie musisz tego robić pojedynczo. Po prostu zrób test dla tych, które nie są alfanumeryczne. Jeśli zostanie znaleziony, weryfikacja nie powiedzie się.

function validateCode(){
    var TCode = document.getElementById('TCode').value;
    if( /[^a-zA-Z0-9]/.test( TCode ) ) {
       alert('Input is not alphanumeric');
       return false;
    }
    return true;     
 }

Jeśli istnieje co najmniej jedno dopasowanie niealfanumeryczne, będzie return false.


6

Stworzyłbym prototypową metodę typu String:

String.prototype.isAlphaNumeric = function() {
  var regExp = /^[A-Za-z0-9]+$/;
  return (this.match(regExp));
};

Wtedy użycie byłoby następujące:

var TCode = document.getElementById('TCode').value;
return TCode.isAlphaNumeric()


2
DJDavid98: Nie sądzę, żeby obowiązywała tu zasada „nie modyfikuj obiektów, których nie jesteś właścicielem”. Justin po prostu rozszerzał możliwości Stringa, nie modyfikując istniejących funkcjonalności. Z perspektywy w świecie C # byłoby to uważane za całkowicie prawidłowe użycie metody rozszerzenia. Nawet jeśli pewnego dnia "String.isAlphaNumeric (): boolean" zostałby zaimplementowany przez producentów przeglądarek, ani sygnatura, ani akcja nie uległyby zmianie, więc nie widzę żadnych ograniczeń w utrzymywalności w tym konkretnym przykładzie. To, że coś jest regułą, nie oznacza, że ​​nie ma wyjątków.
Risto Välimäki

5
    // On keypress event call the following method
    function AlphaNumCheck(e) {
        var charCode = (e.which) ? e.which : e.keyCode;
        if (charCode == 8) return true;

        var keynum;
        var keychar;
        var charcheck = /[a-zA-Z0-9]/;
        if (window.event) // IE
        {
            keynum = e.keyCode;
        }
        else {
            if (e.which) // Netscape/Firefox/Opera
            {
                keynum = e.which;
            }
            else return true;
        }

        keychar = String.fromCharCode(keynum);
        return charcheck.test(keychar);
    }

Co więcej, ten artykuł pomaga również zrozumieć alfanumeryczną walidację JavaScript.


4

Przepraszam wszystkich, bez kontrowersji. Ale żeby społeczność rozwijała się tak, jak mnie rozwijała przez te lata, dobrze jest zrobić kilka notatek.

Prawdziwy ciąg alfanumeryczny jest podobny, "0a0a0a0b0c0d"a nie podobny "000000"lub "qwertyuio".

Wszystkie odpowiedzi, które tu przeczytałem, truew obu przypadkach wróciły . I wybacz mi, IMHO, to nie jest w porządku .

Jeśli chcę sprawdzić, czy mój "00000"ciąg jest alfanumem, moja „ludzka” odpowiedź jest niewątpliwie FAŁSZ.

Czemu? Prosty. Nie mogę znaleźć żadnej litery. Czyli jest prostym ciągiem liczbowym [0-9].

Z drugiej strony, gdybym chciał sprawdzić swój "abcdefg"ciąg, moja „ludzka” odpowiedź jest nawet FAŁSZ. Nie widzę liczb, więc nie są alfanumeryczne. Tylko alfa [a-zA-Z].

Odpowiedź Michaela Martina-Smuckera była pouczająca.

Jednak miał na celu osiągnięcie lepszej wydajności zamiast regex. To prawda, używając niskiego poziomu, uzyskuje się lepszą wydajność. Ale wyniki są takie same. Ciągi "0123456789"(tylko numeryczne), "qwertyuiop"(tylko alfa) i "0a1b2c3d4f4g"(alfanumeryczne) są zwracane TRUEjako alfanumeryczne. Ten sam /^[a-z0-9]+$/isposób wyrażenia regularnego . Powód, dla którego wyrażenie regularne nie działa, jest tak prosty, jak oczywisty. Składnia []wskazuje lub nie i . Zatem, jeśli składa się tylko z liczb lub tylko z liter, zwraca wyrażenie regularne true.

Jednak odpowiedź Michaela Martina-Smuckera była mimo wszystko pouczająca. Dla mnie. Pozwoliło mi to myśleć „na niskim poziomie”, aby stworzyć prawdziwą funkcję, która w sposób jednoznaczny przetwarza ciąg alfanumeryczny. Nazwałem to funkcją względną PHP ctype_alnum( edytuj 2020-02-18: Gdzie jednak sprawdza OR, a nie AND ).

Oto kod:

function ctype_alnum(str) {
  var code, i, len;
    var isNumeric = false, isAlpha = false; //I assume that it is all non-alphanumeric



  for (i = 0, len = str.length; i < len; i++) {
    code = str.charCodeAt(i);


        switch (true){
            case code > 47 && code < 58: // check if 0-9
                isNumeric = true;
                break;
            case (code > 64 && code < 91) || (code > 96 && code < 123): //check if A-Z or a-z
                isAlpha = true;
                break;
            default: // not 0-9, not A-Z or a-z
                return false; //stop function with false result, no more checks

        }

  }

  return isNumeric && isAlpha; //return the loop results, if both are true, the string is certainly alphanumeric
};

... a oto DEMO

Przyszedłem do tej dyskusji, ponieważ szukałem alternatywy w javascript do funkcji PHP. Nie mogę znaleźć odpowiedź „ready-to-Go”, ale jak to często bywa na Stackoverflow, pojęcie wiedzy i porównania z siebie jest czymś wzniosłym, że prowadzi cię do myślenia o czyjąś odpowiedź i znaleźć razem rozwiązanie byłaś szukasz, ale nie sądziłeś, że o tym wiesz.

I udostępnij to!

Najlepsza

Oscar


Powyższe rozwiązuje alphaAndNumeric, a nie alphaNumeric. return isNumeric || isAlpha;jest alfanumeryczny. Powyższe może być pomocne dla niektórych.
TamusJRoyce

1
@TamusJRoyce oczywiście. Ale obraz, aby sprawdzić numer VAT, który w niektórych przypadkach jest tylko numeryczny, aw innym musi być alfanumeryczny. Nawiasem mówiąc, dopiero teraz zdaję sobie sprawę, moja wina, że ​​względna funkcja PHP przewiduje OR zamiast AND. Co jest problemem, ponieważ musiałem zmodyfikować wszystkie kody moich aplikacji PHP, tworząc funkcję ad-hoc, która zapewniała AND
Oscar Zarrus

3

W ciasnej pętli prawdopodobnie lepiej unikać wyrażeń regularnych i zakodować swoje znaki na stałe:

const CHARS = new Set("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
function isAlphanumeric(char) {
    return CHARS.has(char);
}

Czy możesz to wyjaśnić
lazydeveloper

2
Ten kod to O (N ^ 2) podczas skanowania całego ciągu w pętli i spowoduje znacznie gorszą wydajność niż nawet najgorsze przedstawione rozwiązania wyrażeń regularnych (np. Użytkownik przechodzi we wszystkich 'Z', indexOf () musi skanować do koniec dla każdego znaku). Nie tylko potencjalnie pociąga za sobą narzut związany ze skanowaniem całego ciągu 0-Z (wykonując średnio 18 porównań znaków na wywołanie), ale także dwa wywołania funkcji o wartości narzutu na znak ciągu źródłowego - dość znacząca stała wartość czasu! Kod może nawet wprowadzić lukę DoS w zależności od tego, gdzie jest używany.
CubicleSoft

1
Masz absolutną rację, CubicleSoft. Zaktualizowałem odpowiedź, aby użyć zestawu JS.
Malganis

0

Aby sprawdzić, czy input_string jest alfanumeryczny, po prostu użyj:

input_string.match(/[^\w]|_/) == null
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.