RegEx untuk memastikan bahwa string berisi setidaknya satu huruf kecil, huruf besar, angka dan simbol

156

Apa itu regex untuk memastikan bahwa string yang diberikan mengandung setidaknya satu karakter dari masing-masing kategori berikut.

  • Huruf kecil
  • Huruf kapital
  • Angka
  • Simbol

Aku tahu pola set individu yaitu [a-z], [A-Z], \ddan _|[^\w](aku punya mereka benar, bukan?).

Tetapi bagaimana saya menggabungkan mereka untuk memastikan bahwa string berisi semua ini dalam urutan apa pun?

Amarghosh
sumber
Platform / regex-dialek apa? Jawaban Bart benar, tetapi pernyataan lookahead tidak dapat diandalkan dalam JavaScript, misalnya.
bobince
Tidak ada tempat khususnya - saya sedang belajar regex. Apakah ada alternatif yang bisa digunakan dalam javascript?
Amarghosh
@ sejak Halo, saya mencoba mencari tahu mengapa pernyataan lookahead tidak dapat diandalkan di Javascript. Apakah ada Langgan ini?
Chris Bier
@ ChrisB: Ada bug IE / JScript yang benar-benar membingungkan: blog.stevenlevithan.com/archives/regex-lookahead-bug
bobince

Jawaban:

349

Jika Anda memerlukan satu regex tunggal, coba:

(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*\W)

Penjelasan singkat:

(?=.*[a-z])        // use positive look ahead to see if at least one lower case letter exists
(?=.*[A-Z])        // use positive look ahead to see if at least one upper case letter exists
(?=.*\d)           // use positive look ahead to see if at least one digit exists
(?=.*\W])        // use positive look ahead to see if at least one non-word character exists

Dan saya setuju dengan SilentGhost, \Wmungkin agak luas. Saya akan menggantinya dengan set karakter seperti ini: [-+_!@#$%^&*.,?](jangan ragu untuk menambahkan lebih banyak tentu saja!)

Bart Kiers
sumber
Apa yang akan terjadi jika saya mengubah yang terakhir .+menjadi .*? Saya tidak bisa membuat test case yang gagal .*. Apakah mereka sama dalam konteks ini? "Nol atau lebih karakter" tampaknya baik - hanya mencari konfirmasi.
Amarghosh
@Amarghosh: dalam hal ini, tidak ada bedanya. Karena pandangan positif ke depan, string sudah mengandung setidaknya 4 karakter. Jadi tidak ada bedanya untuk berubah .+menjadi .*atau bahkan .{4,}dalam hal ini.
Bart Kiers
Jika Anda ingin menambahkan sedikit penjelasan, saya mengalami kesulitan memahami bagaimana kombinasi dari lookaheads ini menjamin setidaknya 1 dari setiap set karakter akan hadir
Sharlike
@Sharlike, saya tidak tahu bagaimana cara mengucapkannya kembali agar lebih mudah dimengerti. Terutama di kotak komentar kecil ini. Saya sarankan Anda membaca ini: regular-expressions.info/lookaround.html dan jika Anda masih memiliki pertanyaan, cukup kirimkan pertanyaan Anda sendiri. Semoga berhasil!
Bart Kiers
4
@ikertxu, coba sesuatu seperti ini:^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?!.*[&%$]).{6,}$
Bart Kiers
20

Bart Kiers, regex Anda memiliki beberapa masalah. Cara terbaik untuk melakukannya adalah ini:

(.*[a-z].*)       // For lower cases
(.*[A-Z].*)       // For upper cases
(.*\d.*)          // For digits

Dengan cara ini Anda mencari tidak peduli apakah di awal, di akhir atau di tengah. Dalam Anda miliki, saya memiliki banyak masalah dengan kata sandi yang kompleks.

Juan Furattini
sumber
5
Anda tidak memeriksa simbol seperti yang diminta OP.
Casimir
5

Anda dapat mencocokkan ketiga grup secara terpisah, dan pastikan semuanya ada. Juga, [^\w]tampaknya agak terlalu luas, tetapi jika itu yang Anda inginkan, Anda mungkin ingin menggantinya \W.

SilentGhost
sumber
Terima kasih. Saya tidak mengetahui \ W. Hanya mencarinya untuk menemukan bahwa itu cocok dengan Bukan Kata. Apakah ada perbedaan antara \ W dan [\ W]? Apakah [\ W] hanya mubazir?
Amarghosh
@Amarghosh, ya, \Wdan [\W]menghasilkan hal yang sama.
Bart Kiers