RegEx để đảm bảo rằng chuỗi chứa ít nhất một char chữ thường, char chữ hoa, chữ số và ký hiệu


156

Regex là gì để đảm bảo rằng một chuỗi đã cho chứa ít nhất một ký tự từ mỗi loại sau đây.

  • Chữ thường
  • Nhân vật in hoa
  • Chữ số
  • Biểu tượng

Tôi biết các mô hình tập hợp cá nhân cụ thể là [a-z], [A-Z], \d_|[^\w](tôi nhận họ đúng, phải không?).

Nhưng làm thế nào để tôi kết hợp chúng để đảm bảo rằng chuỗi chứa tất cả những thứ này theo bất kỳ thứ tự nào?


Nền tảng / regex-phương ngữ nào? Câu trả lời của Bart là đúng, nhưng các xác nhận tìm kiếm không đáng tin cậy trong JavaScript, chẳng hạn.
bobince

Không nơi nào đặc biệt - Tôi đang học regex. Có một sự thay thế có thể được sử dụng trong javascript không?
Amarghosh

@bobince Này, tôi đang cố gắng tìm hiểu lý do tại sao các xác nhận tìm kiếm không đáng tin cậy trong Javascript. Có một bài viết về điều này?
Chris Bier

@ChrisB: Có một lỗi IE / JScript thực sự khó hiểu: blog.stevenlevithan.com/archives/regex-lookahead-orms
bobince

Câu trả lời:


349

Nếu bạn cần một regex duy nhất, hãy thử:

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

Một lời giải thích ngắn gọn:

(?=.*[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

Và tôi đồng ý với SilentGhost, \Wcó thể hơi rộng. Tôi sẽ thay thế nó bằng một bộ ký tự như thế này: [-+_!@#$%^&*.,?](cứ thoải mái thêm nhiều thứ nữa!)


Điều gì sẽ xảy ra nếu tôi thay đổi cuối cùng .+thành .*? Tôi không thể đưa ra một trường hợp thử nghiệm thất bại .*. Họ có giống nhau trong bối cảnh này? "Không hoặc nhiều nhân vật" dường như vẫn ổn - chỉ cần tìm kiếm xác nhận.
Amarghosh

@Amarghosh: trong trường hợp này, nó không có gì khác biệt. Do các giao diện tích cực, chuỗi đã chứa ít nhất 4 ký tự. Vì vậy, nó không có sự khác biệt để thay đổi .+thành .*hoặc thậm chí .{4,}cho vấn đề đó.
Bart Kiers

Nếu bạn sẵn sàng thêm một lời giải thích, tôi gặp khó khăn trong việc hiểu làm thế nào sự kết hợp của những cái nhìn này đảm bảo ít nhất 1 trong mỗi bộ ký tự sẽ xuất hiện
Sharlike

@Sharlike, tôi không biết cách viết lại nó để dễ hiểu hơn. Đặc biệt là trong những hộp bình luận nhỏ này. Tôi khuyên bạn nên đọc cái này: normal-expressions.info/lookaround.html và nếu bạn vẫn còn thắc mắc, chỉ cần đăng câu hỏi của riêng bạn. Chúc may mắn!
Bart Kiers

4
@ikertxu, hãy thử một cái gì đó như thế này:^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?!.*[&%$]).{6,}$
Bart Kiers

20

Bart Kiers, regex của bạn có một vài vấn đề. Cách tốt nhất để làm điều đó là:

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

Theo cách này, bạn đang tìm kiếm bất kể là lúc đầu, ở cuối hay ở giữa. Trong bạn có rất nhiều rắc rối với mật khẩu phức tạp.


5
Bạn không kiểm tra các ký hiệu như OP yêu cầu.
Casimir

5

Bạn có thể kết hợp ba nhóm đó một cách riêng biệt và đảm bảo rằng tất cả chúng đều có mặt. Ngoài ra, [^\w]có vẻ hơi quá rộng, nhưng nếu đó là những gì bạn muốn, bạn có thể muốn thay thế nó bằng \W.


Cảm ơn. Tôi đã không biết về \ W. Chỉ cần nhìn lên và thấy rằng nó phù hợp với Không Word. Có sự khác biệt nào giữa \ W và [\ W] không? Là [\ W] chỉ là dư thừa?
Amarghosh

@Amarghosh, vâng, \W[\W]kết quả tương tự.
Bart Kiers
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.