Regex เพื่อจับคู่สัญลักษณ์:! $% ^ & * () _ + | ~ - = `{} []:"; '<>?,. /


96

ฉันกำลังพยายามสร้างการทดสอบ Regex ใน JavaScript ซึ่งจะทดสอบสตริงเพื่อให้มีอักขระเหล่านี้:

!$%^&*()_+|~-=`{}[]:";'<>?,./

ข้อมูลเพิ่มเติมหากคุณสนใจ :)

สำหรับแอปพลิเคชันเปลี่ยนรหัสผ่านที่ยอดเยี่ยมที่ฉันกำลังทำอยู่ ในกรณีที่คุณสนใจนี่คือส่วนที่เหลือของรหัส

ฉันมีตารางที่แสดงรายการข้อกำหนดรหัสผ่านและเมื่อผู้ใช้ปลายทางพิมพ์รหัสผ่านใหม่มันจะทดสอบอาร์เรย์ของ Regexes และวางเครื่องหมายถูกในแถวตารางที่เกี่ยวข้องถ้ามัน ... เช็คเอาต์ :) ฉันแค่ต้องเพิ่มอันนี้ แทนที่รายการที่ 4 ในvalidationอาร์เรย์

var validate = function(password){
    valid = true;

    var validation = [
        RegExp(/[a-z]/).test(password), RegExp(/[A-Z]/).test(password), RegExp(/\d/).test(password), 
        RegExp(/\W|_/).test(password), !RegExp(/\s/).test(password), !RegExp("12345678").test(password), 
        !RegExp($('#txtUsername').val()).test(password), !RegExp("cisco").test(password), 
        !RegExp(/([a-z]|[0-9])\1\1\1/).test(password), (password.length > 7)
    ]

    $.each(validation, function(i){
        if(this)
            $('.form table tr').eq(i+1).attr('class', 'check');
        else{
            $('.form table tr').eq(i+1).attr('class', '');
            valid = false
        }
    });

    return(valid);

}

ใช่นอกจากนี้ยังมีการตรวจสอบความถูกต้องฝั่งเซิร์ฟเวอร์ที่เกี่ยวข้องด้วย!


9
เป็นเรื่องตลกมากที่คำตอบสำหรับคำถามของคุณอยู่ในชื่อเรื่องยกเว้นการใช้อักขระพิเศษและการใส่เครื่องหมายทับ
sciritai

1
ทำไมไม่ใช้.addClass("check")และ.removeClass("check")? และการเห็นif (someBoolean == true)ในรหัสทำให้ฉันประจบประแจงเสมอ if (someBoolean)เพียงแค่ทำ $(".form table tr").eq(i+1).toggleClass("check", !!this); valid = valid && !!this;หรือดีกว่ายังเพียงแค่ทำ
gilly3

+1 @ gill3 ขอบคุณสำหรับการตรวจสอบโค้ด - ข้อเสนอแนะที่ดีแน่นอน ฉันเคยใช้วิธีการสั้น ๆ เหล่านั้นในอดีต
pixelbobby

@ gilly3 ดูเหมือนว่าจะใช้งานได้ดีใน FF แต่! IE8 รักมือสั้นคนนี้ ฉันพยายามหาว่า IE8 ทำอะไรแตกต่างออกไป
pixelbobby

คำตอบ:


174

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

/[-!$%^&*()_+|~=`{}\[\]:";'<>?,.\/]/

คุณต้องหลีกเลี่ยงอักขระเมตานิพจน์ทั่วไปอื่น ๆ

แก้ไข: ยัติภังค์มีความพิเศษเนื่องจากสามารถใช้เพื่อแสดงช่วงของอักขระได้ คลาสอักขระเดียวกันนี้สามารถทำให้ง่ายขึ้นโดยมีช่วงดังนี้:

/[$-/:-?{-~!"^_`\[\]]/

มีสามช่วง '$' to '/', ':' to '?' และ '{' to '~' สตริงอักขระสุดท้ายไม่สามารถแทนด้วยช่วง:! "^ _` []

ใช้ตาราง ACSIIเพื่อค้นหาช่วงสำหรับคลาสอักขระ


เหตุใดจึงไม่กล่าวถึงตัวบ่งชี้ \ Q และ \ E สำหรับการหลีกเลี่ยงลำดับของอักขระ
SerG

ก่อนที่จะหาวิธีแก้ปัญหานี้ฉันจะลงเส้นทางการยกเว้นคลาสอักขระ: จับคู่ทุกอย่าง แต่อัลฟาตัวเลขช่องว่าง ฯลฯ
Pete Alvin

1
เป็นความรู้ทั่วไปว่ายัติภังค์ต้องมาก่อนหรือไม่? ฉันได้อ่านคำตอบ SO จำนวนมากและแผ่นโกง regex นี่เป็นคำตอบแรกที่ฉันเคยได้ยิน คำตอบของคุณช่วยฉันดราม่าได้มาก ขอบคุณ!
CF_HoneyBadger

2
@SerG \Qและ\Eไม่ทำงานในเครื่องยนต์JS RegExp :(/^\Q.\E$/.test('Q+E'); // true
Paul S.

1
เครื่องหมายแบ็กสแลช @ q4w56 ไม่ได้อยู่ในชุดอักขระที่ระบุในคำถามเดิมดังนั้นการไม่จับคู่แบ็กสแลชจึงถูกต้อง :)
Jeff Hillman

7

วิธีที่ง่ายและสั้นที่สุดในการทำสิ่งนี้:

/[^\p{L}\d\s@#]/u

คำอธิบาย

[^...] จับคู่อักขระเดี่ยวที่ไม่มีอยู่ในรายการด้านล่าง

  • \p{L} => จับคู่ตัวอักษรจากภาษาใดก็ได้

  • \d => จับคู่เลขศูนย์ถึงเก้า

  • \s => จับคู่อักขระล่องหนทุกชนิด

  • @# => @และ#อักขระ

อย่าลืมส่งuแฟล็ก (Unicode)


คุณไม่จำเป็นต้องใช้ ^ เพื่อระบุว่าไม่?
เว็บเบอร์

1
@ เว็บเบอร์ไม่พวกเขาอยู่ในเมืองหลวงและทำให้คำสั่งนี้เป็นลบ ^เป็นสิ่งจำเป็นเมื่อเราใช้\wและ\sตัวอักษรขนาดเล็ก
AmirZpr

3
สิ่งนี้ไม่ได้ตีความว่าภายนอกwหรือภายนอกsและเนื่องจากทั้งสองไม่ได้ตัดกันจริงๆจึงทำให้ผ่านตัวละครทั้งหมดได้หรือไม่? (จึงไม่กรองอะไรเลย)
Zael

2
@Zael คุณพูดถูกนิพจน์ทั่วไปตามที่ระบุไว้ ( /[\W\S]/) ทำให้ทุกอย่างผ่านพ้นไป [^\w\s]เป็นตัวแทนที่ถูกต้องมากขึ้นของสิ่งที่ผมเชื่อว่าอาเมียร์ได้รับที่จะเป็น ในอดีตนิพจน์ทั่วไปจะพูดว่า "จับคู่อะไรก็ได้ที่ไม่ใช่ตัวอักษรและตัวเลขคละกันหรือที่ไม่ใช่ช่องว่าง" ซึ่งตามที่คุณกล่าวมาขอให้ทุกอย่างผ่านเนื่องจากอักขระที่เป็นตัวเลขและตัวอักษรไม่ใช่ช่องว่างและในทางกลับกัน ตัวหลังระบุว่า "จับคู่อะไรก็ได้ที่ไม่ใช่ตัวเลขและตัวอักษรและไม่ใช่ช่องว่าง" แน่นอนข้อยกเว้นนำไปใช้ในการที่ตัวละครสำเนียง (ชอบÀ) [^\w\s]จะจับคู่โดย
Jesse

ไม่รวม _ ถ่าน
MikeSchem

5

ตอบ

/[\W\S_]/

คำอธิบาย

สิ่งนี้จะสร้างคลาสอักขระโดยลบอักขระคำอักขระเว้นวรรคและเพิ่มอักขระขีดล่างกลับ (เนื่องจากขีดล่างเป็นอักขระ "คำ") สิ่งที่เหลือคืออักขระพิเศษ ตัวพิมพ์ใหญ่หมายถึงการปฏิเสธของตัวพิมพ์เล็ก

\Wจะเลือกอักขระที่ไม่ใช่ "word" ทั้งหมดที่เทียบเท่า[^a-zA-Z0-9_]
\Sจะเลือกอักขระที่ไม่ใช่ "ช่องว่าง" ทั้งหมดที่เทียบเท่ากับ[ \t\n\r\f\v]
_จะเลือก "_" เนื่องจากเราปฏิเสธเมื่อใช้\Wและจำเป็นต้องเพิ่มกลับ


MikeSchem คุณเพิ่งพาฉันผ่านไทม์แมชชีน
pixelbobby

ใช่ฉันสังเกตเห็นมัน เก่า แต่ฉันรู้สึกว่าไม่มีคำตอบที่ง่ายที่สุด
MikeSchem

สิ่งนี้แตกต่างจากคำตอบด้านล่างที่ล้มเหลวบนขีดล่างอย่างไร
sf8193

-1
// The string must contain at least one special character, escaping reserved RegEx characters to avoid conflict
  const hasSpecial = password => {
    const specialReg = new RegExp(
      '^(?=.*[!@#$%^&*"\\[\\]\\{\\}<>/\\(\\)=\\\\\\-_´+`~\\:;,\\.€\\|])',
    );
    return specialReg.test(password);
  };

อย่าใช้ตัวRegExpสร้างเมื่อคุณสามารถใช้ตัวอักษร regex ได้ งานหนีน้อยกว่ามาก (ซึ่งส่วนใหญ่ไม่จำเป็นอยู่ดี) และมีประสิทธิภาพมากขึ้นด้วย
Bergi

ทำไมต้องใช้ Lookahead ที่ซับซ้อนในเมื่อคุณสามารถจับคู่ตัวละครได้โดยตรง?
Bergi

คุณสามารถยกตัวอย่าง @Bergi ได้หรือไม่? ฉันไม่เข้าใจสิ่งที่คุณแนะนำ
Arni Gudjonsson

-1

วิธีง่ายๆในการบรรลุเป้าหมายนี้คือเซตลบ [^ \ w \ s] สิ่งนี้จับเป็นหลัก:

  • สิ่งที่ไม่ใช่อักขระที่เป็นตัวอักษรและตัวเลข (ตัวอักษรและตัวเลข)
  • อะไรก็ตามที่ไม่ใช่ช่องว่างแท็บหรือตัวแบ่งบรรทัด (เรียกรวมกันว่าช่องว่าง)

ด้วยเหตุผลบางประการ [\ W \ S] ไม่ทำงานในลักษณะเดียวกันจึงไม่ทำการกรองใด ๆ ความคิดเห็นของ Zael เกี่ยวกับคำตอบข้อใดข้อหนึ่งให้คำอธิบายบางอย่าง


ไม่เครื่องหมายขีดล่างหายไปและอักขระทั้งหมดที่อยู่นอกช่วง ascii และอักขระควบคุมส่วนใหญ่ในช่วง ascii จะตรงกับคลาสนี้ /[^\w\s]/.test('é') # true, /[^\w\s]/.test('_') # false.
Casimir et Hippolyte

-7

แทนที่ตัวอักษรทั้งหมดจากภาษาใดก็ได้ใน 'A' และหากคุณต้องการให้ตัวเลขทั้งหมดเป็น 0:

return str.replace(/[^\s!-@[-`{-~]/g, "A").replace(/\d/g, "0");

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