Найкращий спосіб буквено-цифрової реєстрації в JavaScript


107

Який найкращий спосіб здійснити буквено-цифрову перевірку на INPUTполі в JSP? Я додав свій поточний код

<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
Залежить від того, як ви визначаєте "найкраще". Більшість відповідей нижче пропонують регулярний вираз, який працює набагато повільніше, ніж ваш вихідний код . Я трохи очистив ваш код , який насправді працює дуже добре.
Майкл Мартін-Смукер

Відповіді:


100

Ви можете використовувати цей регулярний вираз /^[a-z0-9]+$/i


4
Звичайно, це передбачає, що порожній рядок ( "") не повинен відповідати.
zzzzBov

15
ñале не підпадає під зразки, проте цілком дієвий знак UTF-8.
Ойбек

8
/ ^ [a-z0-9] + $ / i.test (TCode)
Алекс V

3
Тестування регулярного вираження здається значно повільнішим (66% у Chrome 36) charCodeAt(). Дивіться jsPerf і мою відповідь нижче .
Майкл Мартін-Смукер

5
Цей регулярний вираз не працює зі спеціальними літерами-символами, які використовуються в деяких мовах, наприклад "ą", "ź", "ć" тощо.
Rafał Swacha

79

Первісна схильність запитувача до використання str.charCodeAt(i)виявляється швидшою, ніж альтернатива звичайного вираження. У моєму тесті на jsPerf параметр RegExp працює на 66% повільніше в Chrome 36 (і трохи повільніше в Firefox 31).

Ось очищена версія вихідного коду перевірки, яка отримує рядок і повертає trueабо 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;
};

Звичайно, можуть бути й інші міркування, наприклад, читабельність. Однорядковий регулярний вираз, безумовно, красивіше подивитися. Але якщо ви суворо переймаєтесь швидкістю, ви можете розглянути цю альтернативу.


17
Програмісти люблять зовнішній вигляд коду, але ви бачите його внутрішню красу.
Ziggy

Цікавий альтернативний підхід - ніколи навіть не спадав мені на думку. Я прийшов сюди, маючи на увазі лише регекс!
ozzy432836

Відповідь, яка змушує задуматися і дає зрозуміти, що це означає "програмування". Я використовую ваш спосіб мислення у своїй відповіді
Оскар Зарус

42

Перевірте це за допомогою регулярного вираження.

У javascript regexen немає класів символів POSIX, тому вам потрібно писати діапазони символів вручну:

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

Тут ^означає початок рядка і $означає кінець рядка, і [0-9a-z]+означає один або більше символів від 0до 9АБО від aдо z.

Більше інформації про Jage regexen тут: https://developer.mozilla.org/en/JavaScript/Guide/Regular_Expressions


14
+1 для пояснення основного регулярного вираження та посилання на керівництво, а не надання користувачеві "магічної струни".
Чарльз Бернс

4
@inor ви можете просто додати «я» в кінці регулярного виразу , щоб вказати випадок нечутливість, домен .ru /^[a-z0-9]+$/iі це буде охоплювати як нижні і верхні літери
LJH

33

Вам не потрібно робити це по черзі. Просто зробіть тест на будь-який, який не буквено-цифровий. Якщо такий знайдено, перевірка завершується невдаче.

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

Якщо є хоча б одна відповідність числа, що не має альфа, це буде return false.


6

Я б створив метод прототипу String:

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

Тоді використання буде:

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


2
DJDavid98: Я не думаю, що тут діє правило "не змінювати об'єкти, якими ви не володієте". Джастін просто розширював можливості String, не змінюючи існуючих функцій. В перспективі, у світі C # це буде розглядатися як абсолютно допустиме використання методу розширення. Навіть якщо якийсь день "String.isAlphaNumeric (): boolean" буде впроваджений виробниками браузерів, ні підпис, ні дія фактично не зміниться, тому я не бачу жодного зменшення ремонтопридатності в цьому конкретному прикладі. Те, що щось є правилом, не означає, що винятків немає.
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);
    }

Далі, ця стаття також допомагає зрозуміти буквено-цифрову перевірку JavaScript.


3

Вибачте всіх, суперечок немає. Але для того, щоб громада зростала так, як виросла мене в ці роки, добре зробити кілька записок.

Справжня буквено-числова струна схожа на, "0a0a0a0b0c0d"а не як "000000"або "qwertyuio".

Усі відповіді, які я прочитав тут, повернулися trueв обох випадках. І вибачте, ІМХО, це неправильно .

Якщо я хочу перевірити, чи є в моєму "00000"рядку буквене слово, моя "людська" відповідь, безперечно, ЛЕГА.

Чому? Простий. Я не можу знайти жодного буквенного знаку. Отже, є простим числовим рядком [0-9].

З іншого боку, якщо я хотів перевірити свій "abcdefg"рядок, моя "людська" відповідь навіть помилкова. Я не бачу цифр, тому це не буквено-цифрові. Просто альфа [a-zA-Z].

Відповідь Майкла Мартіна-Смуккера була яскравою .

Однак він мав на меті досягти кращих показників замість регулярного вираження. Це правда, використовуючи спосіб низького рівня, є краща ефективність. Але результати це те саме. Рядки "0123456789"(лише числові), "qwertyuiop"(лише альфа) та "0a1b2c3d4f4g"(буквено-цифрові) повертаються TRUEяк буквено-цифрові. Той самий регекс- /^[a-z0-9]+$/iспосіб. Причина, чому регулярний вираз не працює, настільки ж проста, як і очевидна. Синтаксис []вказує або , ні і . Отже, якщо це лише числовий чи якщо це лише букви, то регекс повертається true.

Але відповідь Майкла Мартіна-Смукера все-таки була яскравою . Для мене. Це дозволило мені думати на "низькому рівні", створити реальну функцію, яка однозначно обробляє буквено-цифрову рядок. Я назвав це як відносна функція PHP ctype_alnum( редагувати 2020-02-18: Де, однак, це перевіряє АБО, а не І ).

Ось код:

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

... і ось ДЕМО

Я прийшов до цього обговорення, тому що шукав альтернативу в JavaScript для функції PHP. Я не знайшов відповіді "готовий до руху", але, як це часто трапляється на "Стакковерф", поняття знання та порівняння один з одним є чимось піднесеним, що змушує задуматися про чиюсь відповідь і знайти разом рішення, яким ви були шукали, але ти не думав, що ти це знаєш.

І поділіться цим!

Найкраще

Оскар


Вищезазначене вирішує alphaAndNumeric, а не alphaNumeric. return isNumeric || isAlpha;є альфа-числовим. Сказане може бути корисним для деяких.
TamusJRoyce

1
@TamusJRoyce звичайно. Але зображення, щоб перевірити номер ПДВ, де в іншому випадку просто числовий, а в іншому випадку повинен бути альфа-і цифровим. До речі, я лише зараз усвідомлюю свою провину, що відносна функція PHP передбачає АБО замість AND. Яка проблема, тому що мені довелося змінити всі коди моїх програм PHP, створивши спеціальну функцію, яка передбачена для AND
Оскар Зарус

3

У тісному циклі, напевно, краще уникати регулярного вираження та жорсткого коду своїх персонажів:

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

Ви можете пояснити це
lazydeveloper

2
Цей код є O (N ^ 2) при скануванні цілого рядка в циклі і призведе до набагато гіршої продуктивності, ніж навіть найгірші представлені рішення для регулярних виразів (наприклад, користувач передає всі 'Z', indexOf () повинен сканувати на кінець для кожного символу). Мало того, що це може призвести до накладних витрат на сканування всього рядка 0-Z (виконуючи, в середньому, 18 порівнянь символів за виклик), але і два виклики функцій, що вартістю накладних витрат на символ вихідного рядка - досить значне постійне значення часу! Код навіть може ввести вразливість DoS залежно від того, де він використовується.
CubicleSoft

1
Ви абсолютно праві, CubicleSoft. Я оновив відповідь, щоб використовувати JS Set.
Малганіс

0

Щоб перевірити, чи введення строку буквено-цифрове, просто використовуйте:

input_string.match(/[^\w]|_/) == null
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.