วิธีที่ดีที่สุดในการตรวจสอบตัวอักษรและตัวเลขใน JavaScript


109

วิธีใดที่ดีที่สุดในการตรวจสอบตัวอักษรและตัวเลขบนINPUTฟิลด์ในJSP? ฉันได้แนบรหัสปัจจุบันของฉัน

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
ขึ้นอยู่กับว่าคุณนิยามว่า "ดีที่สุด" อย่างไร คำตอบด้านล่างส่วนใหญ่แนะนำ regex ซึ่งทำงานช้ากว่าโค้ดเดิมของคุณมาก ฉันได้ทำความสะอาดโค้ดของคุณเล็กน้อยซึ่งทำงานได้ดีมาก
Michael Martin-Smucker

คำตอบ:


101

คุณสามารถใช้นิพจน์นี้ /^[a-z0-9]+$/i


4
แน่นอนว่าสิ่งนี้ถือว่า""ไม่ควรจับคู่สตริงว่าง ( )
zzzzBov

16
ñไม่ตกอยู่ในรูปแบบอย่างไรก็ตาม UTF-8 char ที่ถูกต้องสมบูรณ์
Oybek

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

3
การทดสอบการแสดงออกปกติดูเหมือนจะช้ากว่ามาก (66% ใน Chrome 36) charCodeAt()กว่า ดูjsPerfและคำตอบของฉันด้านล่าง
Michael Martin-Smucker

5
นิพจน์ทั่วไปนี้ใช้ไม่ได้กับอักษรอักขระพิเศษที่ใช้ในบางภาษาเช่น "ą" "ź" "ć" เป็นต้น
Rafał Swacha

80

ความโน้มเอียงที่จะใช้ดั้งเดิมของผู้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;
};

แน่นอนว่าอาจมีข้อควรพิจารณาอื่น ๆ เช่นความสามารถในการอ่าน นิพจน์ทั่วไปหนึ่งบรรทัดนั้นดูดีกว่าอย่างแน่นอน แต่ถ้าคุณสนใจเรื่องความเร็วอย่างเคร่งครัดคุณอาจต้องพิจารณาทางเลือกนี้


18
โปรแกรมเมอร์ชอบรูปลักษณ์ของโค้ด แต่คุณเห็นความงามภายใน
Ziggy

แนวทางอื่นที่น่าสนใจ - ไม่เคยคิดเลยด้วยซ้ำ ฉันมาที่นี่โดยมีเพียง regex ในใจ!
ozzy432836

คำตอบที่ทำให้คุณคิดและทำให้คุณเข้าใจว่า "การเขียนโปรแกรม" หมายถึงอะไร ฉันใช้วิธีคิดของคุณในคำตอบของฉัน
Oscar Zarrus

43

ตรวจสอบด้วย regex

Javascript regexen ไม่มีคลาสอักขระ POSIX ดังนั้นคุณต้องเขียนช่วงอักขระด้วยตนเอง:

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

นี่^หมายถึงจุดเริ่มต้นของสตริงและ$หมายถึงการสิ้นสุดของสตริงและ[0-9a-z]+วิธีการอย่างใดอย่างหนึ่งหรือมากกว่าของตัวละครจาก0ไป9หรือจากไปaz

ข้อมูลเพิ่มเติมเกี่ยวกับ Javascript regexen ที่นี่: https://developer.mozilla.org/en/JavaScript/Guide/Regular_Expressions


14
+1 สำหรับอธิบาย regex พื้นฐานและลิงก์ไปยังคำแนะนำแทนที่จะให้ "magic string" แก่ผู้ใช้
Charles Burns

4
@ หรือคุณสามารถเพิ่ม 'i' ที่ส่วนท้ายของ regex เพื่อระบุตัวพิมพ์เล็กและใหญ่, .ie /^[a-z0-9]+$/iซึ่งจะครอบคลุมทั้งตัวอักษรตัวพิมพ์เล็กและตัวพิมพ์ใหญ่
LJH

35

คุณไม่จำเป็นต้องทำทีละอย่าง เพียงทดสอบสิ่งที่ไม่ใช่ตัวอักษรและตัวเลข หากพบการตรวจสอบจะล้มเหลว

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.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


5

นี่คือบันทึกบางส่วน: ชุดตัวเลขจริงเป็นเหมือน"0a0a0a0b0c0d"และไม่เหมือนหรือ"000000""qwertyuio"

คำตอบทั้งหมดที่ฉันอ่านที่นี่ส่งคืนtrueทั้งสองกรณี นี้ไม่ถูกต้อง

หากฉันต้องการตรวจสอบว่า"00000"สตริงของฉันเป็นตัวเลขและตัวอักษรหรือไม่สัญชาตญาณของฉันก็ไม่ต้องสงสัยเลย

ทำไม? เรียบง่าย ฉันไม่พบตัวอักษรใด ๆ [0-9]ดังนั้นเป็นสตริงตัวเลขที่เรียบง่าย

ในทางกลับกันถ้าฉันต้องการตรวจสอบ"abcdefg"สตริงของฉันสัญชาตญาณของฉันก็ยังคงเป็นเท็จ ฉันไม่เห็นตัวเลขดังนั้นจึงไม่ใช่ตัวเลขและตัวอักษร [a-zA-Z]อัลฟาเพียง

คำตอบไมเคิลมาร์ติน Smucker ของได้รับการส่องสว่าง

อย่างไรก็ตามเขามุ่งเป้าไปที่การบรรลุประสิทธิภาพที่ดีขึ้นแทนที่จะเป็น regex นี่เป็นเรื่องจริงโดยใช้วิธีระดับต่ำจะมีประสิทธิภาพที่ดีกว่า แต่ผลลัพธ์มันเหมือนกัน สตริง"0123456789"(เฉพาะตัวเลข) "qwertyuiop"(เฉพาะอัลฟา) และ"0a1b2c3d4f4g"(ตัวอักษรและตัวเลข) จะแสดงผลTRUEเป็นตัวอักษรและตัวเลข /^[a-z0-9]+$/iวิธีregex เดียวกัน สาเหตุที่ regex ไม่ทำงานนั้นง่ายอย่างที่เห็นได้ชัด ไวยากรณ์[]บ่งชี้หรือไม่และ ดังนั้นถ้ามันเป็นเพียงตัวเลขหรือtrueถ้ามันเป็นตัวอักษรเท่านั้นผลตอบแทน regex

แต่คำตอบของ Michael Martin-Smuckerก็ยังส่องสว่าง สำหรับฉัน. มันช่วยให้ฉันคิดที่ "ระดับต่ำ" เพื่อสร้างฟังก์ชันจริงที่ประมวลผลสตริงตัวอักษรและตัวเลขอย่างไม่น่าสงสัย ฉันเรียกมันว่าเป็นฟังก์ชันสัมพัทธ์ของ PHP ctype_alnum( แก้ไข 2020-02-18: อย่างไรก็ตามสิ่งนี้ตรวจสอบหรือไม่ใช่ AND )

นี่คือรหัส:


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
}

และนี่คือการสาธิต:

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

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

$("#input").on("keyup", function(){

if ($(this).val().length === 0) {$("#results").html(""); return false};
var isAlphaNumeric = ctype_alnum ($(this).val());
    $("#results").html(
        (isAlphaNumeric) ? 'Yes' : 'No'
        )
        
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="input">

<div> is Alphanumeric? 
<span id="results"></span>
</div>

นี่คือการนำวิธีการของMichael Martin-Smucker ไปใช้ใน JavaScript


ข้างต้นแก้ alphaAndNumeric ไม่ใช่ alphaNumeric return isNumeric || isAlpha;เป็น alphaNumeric ข้างต้นอาจเป็นประโยชน์กับบางคน
TamusJRoyce

1
@TamusJRoyce แน่นอน. แต่รูปภาพสำหรับตรวจสอบหมายเลข VAT บางส่วนซึ่งในบางกรณีเป็นเพียงตัวเลขและในกรณีอื่นต้องเป็นตัวอักษรและตัวเลข อย่างไรก็ตามตอนนี้ฉันรู้แล้วว่าความผิดของฉันคือฟังก์ชัน PHP สัมพัทธ์มองเห็นหรือแทนที่จะเป็น AND ซึ่งเป็นปัญหาเพราะฉันต้องแก้ไขโค้ดทั้งหมดของแอปพลิเคชัน PHP ของฉันสร้างฟังก์ชันเฉพาะกิจที่มีให้สำหรับ AND
Oscar Zarrus

3

ในการวนซ้ำการหลีกเลี่ยง regex และ hardcode ตัวละครของคุณอาจจะดีกว่า:

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

คุณช่วยอธิบายได้
ไหม

2
รหัสนี้คือ O (N ^ 2) เมื่อสแกนสตริงทั้งหมดในลูปและจะส่งผลให้ประสิทธิภาพแย่ลงมากยิ่งกว่าแม้แต่โซลูชัน regex ที่แย่ที่สุดที่นำเสนอ (เช่นผู้ใช้ส่งใน 'Z ทั้งหมด indexOf () ต้องสแกนไปที่ สิ้นสุดสำหรับแต่ละอักขระ) ไม่เพียง แต่อาจต้องเสียค่าใช้จ่ายในการสแกนสตริง 0-Z ทั้งหมด (โดยเฉลี่ยการเปรียบเทียบอักขระ 18 ตัวต่อการโทร) แต่ยังรวมถึงการเรียกใช้ฟังก์ชันสองค่าที่มีค่าใช้จ่ายต่ออักขระของสตริงต้นทางซึ่งเป็นค่าเวลาคงที่ที่ค่อนข้างสำคัญ! โค้ดอาจทำให้เกิดช่องโหว่ DoS ขึ้นอยู่กับว่าจะใช้งานที่ไหน
CubicleSoft

1
คุณมีสิทธิ์อย่างแน่นอน CubicleSoft ฉันอัปเดตคำตอบเพื่อใช้ JS Set
Malganis

1

ในการตรวจสอบว่า input_string เป็นตัวอักษรและตัวเลขหรือไม่ให้ใช้:

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

0

หากคุณต้องการโซลูชันแบบซับเดียวที่ง่ายที่สุดให้ไปหาคำตอบที่ยอมรับซึ่งใช้ regex

อย่างไรก็ตามหากคุณต้องการโซลูชันที่เร็วขึ้นนี่คือฟังก์ชันที่คุณสามารถมีได้

console.log(isAlphaNumeric('a')); // true
console.log(isAlphaNumericString('HelloWorld96')); // true
console.log(isAlphaNumericString('Hello World!')); // false

/**
 * Function to check if a character is alpha-numeric.
 *
 * @param {string} c
 * @return {boolean}
 */
function isAlphaNumeric(c) {
  const CHAR_CODE_A = 65;
  const CHAR_CODE_Z = 90;
  const CHAR_CODE_AS = 97;
  const CHAR_CODE_ZS = 122;
  const CHAR_CODE_0 = 48;
  const CHAR_CODE_9 = 57;

  let code = c.charCodeAt(0);

  if (
    (code >= CHAR_CODE_A && code <= CHAR_CODE_Z) ||
    (code >= CHAR_CODE_AS && code <= CHAR_CODE_ZS) ||
    (code >= CHAR_CODE_0 && code <= CHAR_CODE_9)
  ) {
    return true;
  }

  return false;
}

/**
 * Function to check if a string is fully alpha-numeric.
 *
 * @param {string} s
 * @returns {boolean}
 */
function isAlphaNumericString(s) {
  for (let i = 0; i < s.length; i++) {
    if (!isAlphaNumeric(s[i])) {
      return false;
    }
  }

  return true;
}

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.