Cara terbaik untuk memeriksa alfanumerik di Javascript

107

Apa cara terbaik untuk melakukan pemeriksaan alfanumerik pada suatu INPUTbidang JSP? Saya telah melampirkan kode saya saat ini

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

t0mcat
sumber
2
Tergantung bagaimana Anda mendefinisikan "terbaik". Sebagian besar jawaban di bawah menyarankan regex, yang kinerjanya jauh lebih lambat daripada kode asli Anda . Saya telah membersihkan sedikit kode Anda , yang sebenarnya berkinerja sangat baik.
Michael Martin-Smucker

Jawaban:

100

Anda dapat menggunakan regex ini /^[a-z0-9]+$/i

Mahesh Velaga
sumber
4
tentu saja ini mengasumsikan bahwa string kosong ( "") tidak boleh cocok.
zzzzBov
15
ñtidak termasuk dalam pola namun karakter UTF-8 sepenuhnya valid.
Oybek
8
/ ^ [a-z0-9] + $ / i.test (TCode)
Alex V
3
Menguji ekspresi reguler tampaknya jauh lebih lambat (66% di Chrome 36) daripada charCodeAt(). Lihat jsPerf dan jawaban saya di bawah .
Michael Martin-Smucker
5
Regex ini tidak berfungsi dengan huruf berkarakter khusus yang digunakan dalam beberapa bahasa, seperti "ą", "ź", "ć", dll.
Rafał Swacha
79

Kecenderungan asli penanya untuk menggunakan str.charCodeAt(i)tampaknya lebih cepat daripada alternatif ekspresi reguler. Dalam pengujian saya di jsPerf , opsi RegExp berkinerja 66% lebih lambat di Chrome 36 (dan sedikit lebih lambat di Firefox 31).

Berikut adalah versi pembersihan dari kode validasi asli yang menerima string dan mengembalikan trueatau 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;
};

Tentu saja, mungkin ada pertimbangan lain, seperti keterbacaan. Ekspresi reguler satu baris jelas lebih cantik untuk dilihat. Tetapi jika Anda sangat memperhatikan kecepatan, Anda mungkin ingin mempertimbangkan alternatif ini.

Michael Martin-Smucker
sumber
17
Programmer menyukai tampilan kode, tetapi Anda melihat keindahan dalamnya.
Ziggy
Pendekatan alternatif yang menarik - bahkan tidak pernah terlintas dalam pikiran saya. Saya datang ke sini hanya dengan ekspresi reguler!
ozzy432836
Jawabannya yang membuat Anda berpikir dan membuat Anda mengerti apa artinya "pemrograman". Saya menggunakan cara berpikir Anda, dalam jawaban saya
Oscar Zarrus
42

Periksa dengan regex.

Javascript regexen tidak memiliki kelas karakter POSIX, jadi Anda harus menulis rentang karakter secara manual:

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

Di sini ^berarti awal string dan $berarti akhir string, dan [0-9a-z]+berarti satu atau lebih karakter dari 0ke 9ATAU dari ake z.

Informasi lebih lanjut tentang Javascript regexen di sini: https://developer.mozilla.org/en/JavaScript/Guide/Regular_Expressions

Mischa Arefiev
sumber
14
+1 untuk menjelaskan regex dasar dan menautkan ke panduan, daripada memberikan "string ajaib" kepada pengguna.
Charles Burns
4
@ atau Anda dapat menambahkan 'i' di akhir regex untuk menentukan ketidakpekaan huruf besar / kecil, .ie /^[a-z0-9]+$/idan ini akan mencakup huruf besar dan kecil
LJH
33

Anda tidak perlu melakukannya satu per satu. Lakukan saja tes untuk semua itu bukan alfanumerik. Jika ditemukan, validasi gagal.

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

Jika ada setidaknya satu kecocokan dari non alfa numerik, itu akan return false.

pengguna113716
sumber
6

Saya akan membuat metode prototipe String:

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

Kemudian, penggunaannya adalah:

var TCode = document.getElementById('TCode').value;
return TCode.isAlphaNumeric()
Justin
sumber
2
DJDavid98: Saya tidak berpikir bahwa aturan "jangan memodifikasi objek yang tidak Anda miliki" berlaku di sini. Justin hanya memperluas kemampuan String, tidak mengubah fungsi yang ada. Untuk perspektif, di dunia C #, itu akan dianggap sebagai penggunaan metode ekstensi yang benar-benar valid. Bahkan jika suatu hari "String.isAlphaNumeric (): boolean" akan diterapkan oleh produsen browser, baik tanda tangan maupun tindakan tidak akan benar-benar berubah, jadi saya tidak dapat melihat pengurangan apa pun dalam pemeliharaan dalam contoh khusus ini. Bahwa sesuatu adalah aturan tidak berarti tidak ada pengecualian.
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);
    }

Lebih lanjut, artikel ini juga membantu memahami validasi alfanumerik JavaScript.

Neerajan
sumber
3

Permisi semua, tidak ada kontroversi. Tetapi agar komunitas dapat tumbuh seperti yang telah menumbuhkan saya di tahun-tahun ini, ada baiknya membuat beberapa catatan.

String alfanumerik yang sebenarnya adalah seperti "0a0a0a0b0c0d"dan bukan seperti "000000"atau "qwertyuio".

Semua jawaban yang saya baca di sini, dikembalikan truedalam kedua kasus. Dan maafkan saya, IMHO, ini tidak benar .

Jika saya ingin memeriksa apakah "00000"string saya alfanum, jawaban "manusia" saya tidak diragukan lagi SALAH.

Mengapa? Sederhana. Saya tidak dapat menemukan karakter huruf apa pun. Jadi, adalah string numerik sederhana [0-9].

Di sisi lain, jika saya ingin memeriksa "abcdefg"string saya, jawaban "manusia" saya malah SALAH. Saya tidak melihat angka, jadi bukan alfanumerik. Hanya alfa [a-zA-Z].

Jawaban Michael Martin-Smucker telah mencerahkan.

Namun dia bertujuan untuk mencapai kinerja yang lebih baik daripada regex. Ini benar, menggunakan cara tingkat rendah akan menghasilkan kinerja yang lebih baik. Tapi hasilnya sama saja. String "0123456789"(hanya numerik), "qwertyuiop"(hanya alfa) dan "0a1b2c3d4f4g"(alfanumerik) ditampilkan TRUEsebagai alfanumerik. /^[a-z0-9]+$/iCara regex yang sama . Alasan mengapa regex tidak berfungsi sesederhana itu. Sintaksnya []menunjukkan atau , bukan dan . Jadi, jika hanya numerik atau hanya huruf, regex mengembalikan true.

Tapi, jawaban Michael Martin-Smucker tetap mencerahkan. Untuk saya. Ini memungkinkan saya untuk berpikir di "level rendah", untuk membuat fungsi nyata yang memproses string alfanumerik dengan jelas. Saya menyebutnya seperti fungsi relatif PHP ctype_alnum( edit 2020-02-18: Di mana, bagaimanapun, ini memeriksa ATAU dan bukan DAN ).

Berikut kodenya:

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

... dan inilah DEMO

Saya datang ke diskusi ini karena saya mencari alternatif dalam javascript untuk fungsi PHP. Saya tidak menemukan jawaban "ready-to-go", tetapi seperti yang sering terjadi di Stackoverflow, konsep pengetahuan dan perbandingan satu sama lain adalah sesuatu yang luhur, yang membuat Anda berpikir tentang jawaban seseorang dan menemukan bersama solusi Anda. mencari, tetapi Anda tidak berpikir Anda mengetahuinya.

Dan bagikan!

Terbaik

Oscar

Oscar Zarrus
sumber
Di atas memecahkan alphaAndNumeric, bukan alphaNumeric. return isNumeric || isAlpha;adalah alphaNumeric. Di atas mungkin bermanfaat bagi beberapa orang.
TamusJRoyce
1
@TamusJRoyce tentu saja. Tetapi gambar untuk memeriksa beberapa nomor PPN dimana dalam beberapa kasus hanya berupa angka dan dalam kasus lain harus alfa & numerik. Omong-omong, saya baru menyadari sekarang, kesalahan saya, bahwa fungsi relatif PHP memperkirakan OR, bukan AND. Yang menjadi masalah karena saya harus memodifikasi semua kode aplikasi PHP saya, membuat fungsi ad-hoc yang disediakan untuk AND
Oscar Zarrus
3

Dalam loop yang ketat, mungkin lebih baik untuk menghindari regex dan hardcode karakter Anda:

const CHARS = new Set("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
function isAlphanumeric(char) {
    return CHARS.has(char);
}
Malganis
sumber
dapatkah Anda menjelaskan ini
lazydeveloper
2
Kode ini adalah O (N ^ 2) saat memindai seluruh string dalam satu loop dan akan menghasilkan kinerja yang jauh lebih buruk daripada solusi regex terburuk yang disajikan (mis. Pengguna memasukkan semua 'Z, indexOf () harus memindai ke berakhir untuk setiap karakter). Tidak hanya berpotensi menimbulkan overhead pemindaian seluruh string 0-Z (melakukan, rata-rata, perbandingan 18 karakter per panggilan) tetapi juga dua panggilan fungsi senilai overhead per karakter dari string sumber - nilai waktu konstan yang cukup signifikan! Kode tersebut bahkan dapat menyebabkan kerentanan DoS tergantung di mana ia digunakan.
CubicleSoft
1
Anda CubicleSoft benar. Saya memperbarui jawaban untuk menggunakan JS Set.
Malganis
0

Untuk memeriksa apakah input_string adalah alfanumerik, cukup gunakan:

input_string.match(/[^\w]|_/) == null
Mark Baaijens
sumber