Javascript'te alfanümerik kontrol etmenin en iyi yolu


107

İçindeki bir INPUTalanda alfanümerik kontrol yapmanın en iyi yolu nedir JSP? Mevcut kodumu ekledim

<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
"En iyi" yi nasıl tanımladığınıza bağlı. Aşağıdaki yanıtların çoğu, orijinal kodunuzdan çok daha yavaş performans gösteren normal ifadeyi önerir . Ben ettik senin kod temizledik aslında çok iyi bir performans biraz.
Michael Martin-Smucker

Yanıtlar:


100

Bu normal ifadeyi kullanabilirsiniz /^[a-z0-9]+$/i


4
Tabii ki bu, boş dizenin ( "") eşleşmemesi gerektiğini varsayar .
zzzzBov

15
ñkalıba girmez ancak tamamen geçerli UTF-8 karakter.
Oybek

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

3
Normal bir ifadeyi test etmek, olduğundan çok daha yavaş görünmektedir (Chrome 36'da% 66) charCodeAt(). Bkz jsPerf ve aşağıda cevabım .
Michael Martin-Smucker

5
Bu normal ifade, "ą", "ź", "ć" gibi bazı dillerde kullanılan özel karakter harfleriyle çalışmaz.
Rafał Swacha

79

Soruyu soranın orijinal kullanım eğilimi str.charCodeAt(i), normal ifade alternatifinden daha hızlı görünmektedir. In jsPerf benim testi (biraz daha yavaş Firefox 31'de ve) Chrome 36 RegExp seçenek gerçekleştirdiği% 66 daha yavaş.

İşte bir dize ve döner alır orijinal doğrulama kodu temizlenmiş sürümü trueveya 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;
};

Elbette okunabilirlik gibi başka hususlar da olabilir. Tek satırlık bir düzenli ifadeye bakmak kesinlikle daha güzeldir. Ancak kesinlikle hız ile ilgileniyorsanız, bu alternatifi düşünmek isteyebilirsiniz.


17
Programcılar kodun görünümünü severler ama siz onun iç güzelliğini görürsünüz.
Ziggy

İlginç bir alternatif yaklaşım - aklımdan hiç geçmedi. Buraya sadece normal ifadeyle geldim!
ozzy432836

Sizi düşündüren ve bunun "programlama" nın ne anlama geldiğini anlamanızı sağlayan yanıt. Ben de, düşünme yolunuzu kullanın Cevabıma
Oscar Zarrus

42

Bir normal ifadeyle kontrol edin.

Javascript regexen'in POSIX karakter sınıfları yoktur, bu nedenle karakter aralıklarını manuel olarak yazmanız gerekir:

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

Burada ^dizenin başlangıcı anlamına gelir ve dizenin $sonu anlamına gelir ve [0-9a-z]+' 0den 9OR' aye kadar bir veya daha fazla karakter anlamına gelirz .

Javascript regexen hakkında daha fazla bilgiyi burada bulabilirsiniz: https://developer.mozilla.org/en/JavaScript/Guide/Regular_Expressions


14
Kullanıcıya "sihirli bir dizi" vermek yerine temel normal ifadeyi açıklamak ve bir kılavuza bağlantı vermek için +1.
Charles Burns

4
@inor, büyük / küçük harfe duyarlılığı belirtmek için normal ifadenin sonuna 'i' ekleyebilirsiniz, .ie /^[a-z0-9]+$/ive bu hem küçük hem de büyük harfleri kapsayacaktır
LJH

33

Her seferinde bir tane yapmanıza gerek yok. Alfasayısal olmayanlar için bir test yapın . Biri bulunursa, doğrulama başarısız olur.

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

Alfasayısal olmayan en az bir eşleşme varsa, olacaktır return false.


6

Bir String prototip yöntemi oluşturardım:

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

Daha sonra kullanım şöyle olacaktır:

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


2
DJDavid98: "Sahip olmadığınız nesneleri değiştirmeyin" kuralının burada geçerli olduğunu sanmıyorum. Justin sadece String'in yeteneklerini genişletiyordu, mevcut işlevleri değiştirmiyordu. Perspektif açısından, C # dünyasında bu, bir uzatma yönteminin tamamen geçerli bir kullanımı olarak kabul edilir. Bir gün "String.isAlphaNumeric (): boolean" tarayıcı üreticileri tarafından uygulanacak olsa bile, ne imza ne de eylem gerçekte değişmeyecek, bu nedenle bu örnekte sürdürülebilirlikte herhangi bir azalma göremiyorum. Bir şeyin bir kural olması, istisnaların olmadığı anlamına gelmez.
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);
    }

Ayrıca, bu makale JavaScript alfanümerik doğrulamasını anlamaya da yardımcı olur.


4

Affedersiniz, tartışma yok. Ancak bu yıllarda beni büyüdükçe topluluğun da büyümesi için bazı notlar almakta fayda var.

Gerçek alfanümerik dizge veya gibi "0a0a0a0b0c0d"değil, gibidir ."000000""qwertyuio"

Her trueiki durumda da burada okuduğum tüm cevaplar geri döndü . Ve affet beni, IMHO, bu doğru değil .

"00000"Dizimin alfanum olup olmadığını kontrol etmek istersem , "insan" cevabım şüphesiz YANLIŞ olacaktır.

Neden? Basit. Herhangi bir harf karakteri bulamıyorum. Yani, basit bir sayısal dizedir [0-9].

Öte yandan, kontrol etmek istersem "abcdefg" , "insan" cevabım YANLIŞ bile olur. Sayıları görmüyorum, bu yüzden alfanümerik değil. Sadece alfa [a-zA-Z].

Michael Martin-Smucker cevabı aydınlatıcı olmuştur.

Ancak, normal ifade yerine daha iyi performans elde etmeyi hedefliyordu. Bu doğru, düşük seviyeli bir yol kullanarak daha iyi bir performans var. Ancak sonuçlar aynı. Dizeler "0123456789"(yalnızca sayısal), "qwertyuiop"(yalnızca alfa) ve "0a1b2c3d4f4g"(alfanümerik) TRUEalfanümerik olarak döndürülür . Aynı normal ifade /^[a-z0-9]+$/iyolu. Normal ifadenin çalışmamasının nedeni açık olduğu kadar basittir. Sözdizimi []gösterir veya değil ve . Dolayısıyla, yalnızca sayısalsa veya yalnızca harflerden oluşuyorsa, normal ifade döndürür true.

Ancak, Michael Martin-Smucker'ın cevabı yine de aydınlatıcıydı. Benim için. Alfasayısal bir dizgeyi kesin olarak işleyen gerçek bir işlev yaratmak için "düşük seviyede" düşünmeme izin verdi. Bunu PHP göreli işlevi olarak adlandırdım ctype_alnum( 2020-02-18'i düzenleyin: Bununla birlikte, bu AND'yi değil VE'yi kontrol eder ).

İşte 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
};

... ve işte DEMO

Bu tartışmaya geldim çünkü javascript'te PHP işlevine bir alternatif arıyordum. "Kullanıma hazır" cevabını bulamadım, ancak Stackoverflow'da sıklıkla olduğu gibi, bilgi kavramı ve birbirleriyle karşılaştırma, sizi birinin cevabı hakkında düşünmeye ve birlikte bulmaya yönlendiren yüce bir şeydir bulunduğunuz çözümü arıyorsun, ama bildiğini düşünmedin.

Ve paylaşın!

En iyi

Oscar


Yukarıdakiler alphaAndNumeric'i çözer, alphaNumeric'i değil. return isNumeric || isAlpha;alphaNumeric olduğunu. Yukarıdakiler bazıları için yardımcı olabilir.
TamusJRoyce

1
@TamusJRoyce tabii ki. Ancak resim, bazı durumlarda yalnızca sayısal, diğer durumlarda alfa ve sayısal olması gereken bazı KDV numaralarını kontrol etmek için. Bu arada, sadece şimdi anlıyorum, benim hatam, göreli PHP işlevi AND yerine OR'yi öngörüyor. Bu bir problem çünkü PHP uygulamalarımın tüm kodlarını değiştirmek zorunda kaldım, AND için sağlanan geçici bir işlev oluşturdum
Oscar Zarrus

3

Sıkı bir döngüde, normal ifadelerden kaçınmak ve karakterlerinizi sabit kodlamak muhtemelen daha iyidir:

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

bunu açıklayabilir misin
lazydeveloper

2
Bu kod, bir döngüdeki tüm dizeyi tararken O (N ^ 2) olur ve sunulan en kötü normal ifade çözümlerinden bile çok daha kötü performansla sonuçlanır (örneğin, bir kullanıcı tüm 'Z'lerde geçer, indexOf (), her karakter için son). Bu, yalnızca potansiyel olarak tüm 0-Z dizgisini taramanın ek yüküne neden olmakla kalmaz (arama başına ortalama 18 karakter karşılaştırması gerçekleştirir), aynı zamanda kaynak dizginin karakteri başına ek yük değerinde iki işlev çağrısı - oldukça önemli bir sabit zaman değeri! Kod, nerede kullanıldığına bağlı olarak bir DoS güvenlik açığı bile getirebilir.
CubicleSoft

1
Kesinlikle haklısınız CubicleSoft. JS Set'i kullanmak için cevabı güncelledim.
Malganis

0

İnput_string'in alfasayısal olup olmadığını kontrol etmek için şunu kullanın:

input_string.match(/[^\w]|_/) == null
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.