2012-03-06 70 views
11

Tôi hiện đang viết một tập lệnh nhỏ để kiểm tra nội dung của mỗi chuỗi.Cách kiểm tra xem chuỗi có ít nhất một chữ cái, số và ký tự đặc biệt trong php

Tôi đã tự hỏi REGEX sẽ làm gì để đảm bảo rằng một chuỗi có một chữ cái (trên hoặc dưới), một chữ số và một ký tự đặc biệt?

Dưới đây là những gì tôi biết cho đến nay (whcih là không nhiều):

if(preg_match('/^[a-zA-Z0-9]+$/i', $string)): 

Trợ giúp sẽ là tuyệt vời!

Cảm ơn bạn!

+2

Hãy xác định những gì bạn có ý nghĩa bởi "nhân vật đặc biệt" –

Trả lời

40

Các đơn giản nhất (và có lẽ tốt nhất) Cách thứ nhất là để làm ba kiểm tra riêng biệt với preg_match:

$containsLetter = preg_match('/[a-zA-Z]/', $string); 
$containsDigit = preg_match('/\d/',   $string); 
$containsSpecial = preg_match('/[^a-zA-Z\d]/', $string); 

// $containsAll = $containsLetter && $containsDigit && $containsSpecial 
+0

đẹp một, làm việc tốt! :) –

+0

@ rybo111: Không, chúng không thể. 'A-z' chứa nhiều ký tự hơn' a-zA-Z'. – Ryan

+1

@ rybo111: Vui lòng ngừng chỉnh sửa câu trả lời của tôi để ít rõ ràng hơn. Không ai “yêu cầu if()” và không giống như bạn không thể sử dụng biến trong một. – Ryan

4

Nó có thể là tốt nhất để sử dụng 3 regexs biệt để làm điều này, vì bạn sẽ cần phải phù hợp 6 khả năng khác nhau , tùy thuộc vào nơi ký tự đặc biệt của bạn nằm trong chuỗi của bạn. Nhưng nếu bạn muốn làm điều đó trong một regex, và ký tự đặc biệt của bạn, nói, [? + @], Có thể:

$string = "[email protected]"; 
$regex = "/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[$%^&]).*$/" 
if (preg_match($regex, $string)) { 
    // special characters 
} 
11

Bạn có thể sử dụng tích cực lookahead để tạo ra một regex duy nhất:

$strongPassword = preg_match('/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[$%^&]).*$/'); 
//            special characters ^^^^ 
5

Tôi đã tìm thấy câu trả lời tuyệt vời ở đây với giải thích để đảm bảo rằng chuỗi nhất định chứa ít nhất một ký tự từ mỗi danh mục sau.

nhân vật Chữ thường, nhân vật chữ hoa, Digit, Symbol

^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*(_|[^\w])).+$ 

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

^ // sự bắt đầu của chuỗi

(?=.*[a-z]) // sử dụng cái nhìn tích cực về phía trước để xem ít nhất một chữ thường có tồn tại không

(?=.*[A-Z]) // sử dụng cái nhìn tích cực về phía trước để xem nếu ít nhất một ký tự chữ hoa tồn tại

(?=.*\d) // sử dụng cái nhìn tích cực về phía trước để xem nếu có ít nhất một chữ số tồn tại

(?=.*[_\W]) // sử dụng cái nhìn tích cực về phía trước để thấy nếu ít nhất một dấu gạch dưới hoặc nhân vật phi-word tồn tại

.+ // nuốt chửng toàn bộ chuỗi

$ // kết thúc chuỗi

Hy vọng sẽ giúp bạn.

3

Một lá thư là \pL, một số là \pN và một char đặc biệt là [what you want], ở đây tôi giả sử nó không phải là một bức thư và không phải là một số, vì vậy regex trông giống như:

/^(?=.*?\pL)(?=.*?\pN)(?=.*[^\pL\pN])/ 
+3

Thật tuyệt khi bạn bao gồm các ký tự không phải tiếng Anh. thường bị bỏ qua. – dval

1

False (câu trả lời lựa chọn ở trên - Cảm ơn!) đã có một cách khá dễ dàng để quấn đầu của bạn xung quanh nó (nếu bạn không quá quen thuộc với regex) và đến với những gì làm việc cho bạn.

tôi chỉ cần đặt trong này để xây dựng một chút:

(bạn có thể dán nó ở http://phptester.net/index.php?lang=en để làm việc với nó)

<?php 

$pass="abc1A"; 

$ucl = preg_match('/[A-Z]/', $pass); // Uppercase Letter 
$lcl = preg_match('/[a-z]/', $pass); // Lowercase Letter 
$dig = preg_match('/\d/', $pass); // Numeral 
$nos = preg_match('/\W/', $pass); // Non-alpha/num characters (allows underscore) 

if($ucl) { 
    echo "Contains upper case!<br>"; 
} 

if($lcl) { 
    echo "Contains lower case!<br>"; 
} 

if($dig) { 
    echo "Contains a numeral!<br>"; 
} 

// I negated this if you want to dis-allow non-alphas/num: 
if(!$nos) { 
    echo "Contains no Symbols!<br>"; 
} 

if ($ucl && $lcl && $dig && !$nos) { // Negated on $nos here as well 
    echo "<br>All Four Pass!!!"; 
} else { 
    echo "<br>Failure..."; 
} 

?> 
Các vấn đề liên quan