Saya membuat regexp untuk validasi sandi yang akan digunakan dalam aplikasi Java sebagai parameter konfigurasi.
Regexpnya adalah:
^.*(?=.{8,})(?=..*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=]).*$
Kebijakan kata sandi adalah:
Setidaknya 8 karakter
Berisi setidaknya satu digit
Berisi setidaknya satu karakter alfa bawah dan satu karakter alfa atas
Berisi setidaknya satu karakter dalam satu set karakter khusus (
@#%$^
dll.)Tidak mengandung spasi, tab, dll.
Saya melewatkan poin 5. Saya tidak dapat memiliki pemeriksaan regexp untuk spasi, tab, carriage return, dll.
Adakah yang bisa membantu saya?
Jawaban:
Coba ini:
Penjelasan:
Sangat mudah untuk menambah, mengubah atau menghapus aturan individu, karena setiap aturan adalah "modul" independen.
The
(?=.*[xyz])
konstruk makan seluruh string (.*
) dan backtracks untuk kejadian pertama di mana[xyz]
bisa cocok. Berhasil jika[xyz]
ditemukan, gagal jika tidak.Alternatif akan menggunakan kualifikasi enggan:
(?=.*?[xyz])
. Untuk pemeriksaan kata sandi, ini tidak akan membuat perbedaan apa pun, untuk string yang lebih panjang, ini bisa menjadi varian yang lebih efisien.Varian yang paling efisien (tetapi yang paling sulit dibaca dan dipelihara, oleh karena itu yang paling rawan kesalahan)
(?=[^xyz]*[xyz])
, tentu saja. Untuk regex dengan panjang ini dan untuk tujuan ini, saya tidak akan merekomendasikan melakukannya dengan cara itu, karena tidak memiliki manfaat nyata.sumber
\\s
. Itu adalah persyaratan Java, bukan persyaratan regex.(?=...)
polanya sehingga cocok dengan pengaturan ekspresi lainnya ..(?=\S+$)
) atau "tidak berisi karakter spasi" ((?!.*\s)
) adalah masalah preferensi. Gunakan apa pun yang Anda suka dengan lebih baik. :)contoh sederhana menggunakan regex
Penjelasan:
(?=.*[0-9])
satu digit harus muncul setidaknya sekali(?=.*[a-z])
huruf kecil harus muncul setidaknya sekali(?=.*[A-Z])
huruf besar harus muncul setidaknya sekali(?=.*[@#$%^&+=])
karakter khusus harus muncul setidaknya sekali(?=\\S+$)
tidak ada spasi kosong yang diperbolehkan di seluruh string.{8,}
setidaknya 8 karaktersumber
Semua jawaban yang diberikan sebelumnya menggunakan teknik yang sama (benar) untuk menggunakan lookahead terpisah untuk setiap persyaratan. Tetapi mereka mengandung beberapa inefisiensi dan bug yang berpotensi besar, tergantung pada bagian belakang yang benar-benar akan menggunakan kata sandi.
Saya akan mulai dengan regex dari jawaban yang diterima:
Pertama-tama, karena Java mendukung
\A
dan\z
saya lebih suka menggunakannya untuk memastikan seluruh string divalidasi, terlepas dariPattern.MULTILINE
. Ini tidak memengaruhi kinerja, tetapi menghindari kesalahan saat ekspresi reguler didaur ulang.Memeriksa bahwa kata sandi tidak mengandung spasi dan memeriksa panjang minimumnya dapat dilakukan dalam sekali jalan dengan menggunakan semua sekaligus dengan meletakkan pembilang variabel
{8,}
pada singkatan\S
yang membatasi karakter yang diizinkan:Jika kata sandi yang diberikan memang mengandung spasi, semua pemeriksaan akan dilakukan, hanya untuk pemeriksaan terakhir gagal pada spasi. Ini dapat dihindari dengan mengganti semua titik dengan
\S
:Titik hanya boleh digunakan jika Anda benar-benar ingin mengizinkan karakter apa pun. Jika tidak, gunakan kelas karakter (dinegasikan) untuk membatasi regex Anda hanya untuk karakter yang benar-benar diizinkan. Meskipun dalam kasus ini tidak ada bedanya, tidak menggunakan titik saat ada hal lain yang lebih sesuai adalah kebiasaan yang sangat baik. Saya melihat terlalu banyak kasus catastrophic backtracking karena pengembang terlalu malas untuk menggunakan sesuatu yang lebih sesuai daripada titik.
Karena ada kemungkinan besar pengujian awal akan menemukan karakter yang sesuai di paruh pertama kata sandi, penghitung malas bisa lebih efisien:
Tetapi sekarang untuk masalah yang sangat penting: tidak ada jawaban yang menyebutkan fakta bahwa pertanyaan asli tampaknya ditulis oleh seseorang yang berpikir dalam ASCII. Tetapi dalam string Java adalah Unicode. Apakah karakter non-ASCII diperbolehkan dalam sandi? Jika ya, hanya spasi ASCII yang tidak diizinkan, atau semua spasi Unicode harus dikecualikan.
Secara default
\s
hanya mencocokkan ruang putih ASCII, jadi kebalikannya\S
cocok dengan semua karakter Unicode (spasi atau tidak) dan semua karakter ASCII non-spasi. Jika karakter Unicode diizinkan tetapi spasi Unicode tidak diperbolehkan,UNICODE_CHARACTER_CLASS
bendera dapat ditentukan untuk\S
mengecualikan spasi kosong Unicode. Jika karakter Unicode tidak diperbolehkan, maka[\x21-\x7E]
dapat digunakan sebagai pengganti\S
untuk mencocokkan semua karakter ASCII yang bukan spasi atau karakter kontrol.Yang membawa kita ke masalah potensial berikutnya: apakah kita ingin mengizinkan karakter kontrol? Langkah pertama dalam menulis regex yang tepat adalah menentukan dengan tepat apa yang ingin Anda cocokkan dan apa yang tidak. Satu-satunya jawaban yang 100% benar secara teknis adalah bahwa spesifikasi kata sandi dalam pertanyaan itu ambigu karena tidak menyatakan apakah rentang karakter tertentu seperti karakter kontrol atau karakter non-ASCII diizinkan atau tidak.
sumber
Anda tidak boleh menggunakan Regex yang terlalu kompleks (jika Anda dapat menghindarinya) karena memang demikian
Meskipun mungkin ada overhead kinerja kecil dalam menggunakan banyak ekspresi reguler kecil, poin di atas membuatnya lebih mudah.
Saya akan menerapkan seperti ini:
sumber
Persyaratan Kata Sandi:
Kata sandi harus menyertakan karakter dari setidaknya dua (2) pengelompokan ini: alfa, numerik, dan karakter khusus.
Saya mengujinya dan berhasil
sumber
Bagi siapa pun yang tertarik dengan persyaratan minimum untuk setiap jenis karakter, saya sarankan untuk membuat ekstensi berikut atas jawaban yang diterima Tomalak:
Perhatikan bahwa ini adalah string pemformatan dan bukan pola regex terakhir. Cukup gantikan% d dengan kemunculan minimum yang diperlukan untuk: digit, huruf kecil, huruf besar, bukan digit / karakter, dan seluruh kata sandi (masing-masing). Kemunculan maksimum tidak mungkin (kecuali Anda menginginkan maksimal 0, secara efektif menolak karakter seperti itu) tetapi itu dapat dengan mudah ditambahkan juga. Perhatikan pengelompokan ekstra di sekitar setiap jenis sehingga batasan min / max memungkinkan kecocokan yang tidak berurutan. Ini bekerja dengan sangat baik untuk sistem di mana kita dapat secara terpusat mengkonfigurasi berapa banyak dari setiap jenis karakter yang kita butuhkan dan kemudian memiliki situs web serta dua platform seluler yang berbeda mengambil informasi itu untuk membangun pola regex berdasarkan string pemformatan di atas.
sumber
Yang ini memeriksa setiap karakter khusus:
sumber
Metode Java siap untuk Anda, dengan parameter
Cukup salin dan tempel dan atur parameter yang Anda inginkan.
Jika Anda tidak menginginkan modul, cukup beri komentar atau tambahkan "jika" seperti yang saya lakukan untuk karakter khusus
sumber
Gunakan perpustakaan Passay yang merupakan api yang kuat.
sumber
Saya pikir ini juga dapat dilakukan (sebagai mode yang lebih sederhana):
[Demo Regex]
sumber
mudah
("^ (? =. * [0-9]) (? =. * [Az]) (? =. * [AZ]) (? =. * [\\ W _]) [\\ S] {8 , 10} $ ")
(? = apa saja) -> berarti positif melihat ke depan pada semua string input dan pastikan untuk kondisi ini tertulis .sample (? =. * [0-9]) -> berarti memastikan satu digit angka tertulis di semua string. jika tidak tertulis return false .
(?! apa saja) -> (sebaliknya) berarti negatif melihat ke depan jika kondisinya tertulis return false .
arti dekat ^ (kondisi) (kondisi) (kondisi) (kondisi) [\ S] {8,10} $
sumber
Penjelasan:
sumber
Anda Juga Dapat Melakukan Seperti Ini.
sumber
Contoh blok kode untuk kata sandi yang kuat:
sumber
RegEx adalah -
sumber