我本可以單獨詢問這三個,但決定合併它們。關於字符串驗證的專家意見?
我想請教一些專家的意見與實例:
如何正確地驗證一個字母數字字符串? (只有拉丁字母&號碼)
如何正確驗證寫入的unicode字符串? (像上面但允許任何國家的字母)
如何正確驗證字符串看起來像電子郵件?我猜最好是
filter_var($string,FILTER_VALIDATE_EMAIL)
(我想這是對URL和IP相同)
謝謝。
我本可以單獨詢問這三個,但決定合併它們。關於字符串驗證的專家意見?
我想請教一些專家的意見與實例:
如何正確地驗證一個字母數字字符串? (只有拉丁字母&號碼)
如何正確驗證寫入的unicode字符串? (像上面但允許任何國家的字母)
如何正確驗證字符串看起來像電子郵件?我猜最好是filter_var($string,FILTER_VALIDATE_EMAIL)
(我想這是對URL和IP相同)
謝謝。
您可能想要使用正則表達式。
不,你不知道。此外,這個答案根本沒有幫助-1 – NikiC 2010-10-16 12:23:01
您的評論確實有幫助嗎?幾乎所有發佈的其他答案都涉及某種形式的正則表達式匹配。 – 2010-10-16 12:28:49
preg_match('/[a-zA-Z0-9]+/', $str)
filter_very整潔,高效的特殊用途,但也是有限的。
你也只是得到一個過濾的返回字符串,你必須與原始字符串進行比較,看它是否適合。
可能有某些要求和/或結構旁邊的允許字符,你不能用這種方式檢查。
最常用的方法是使用pcre函數,特別是preg_match。 其效率非常高,您可以直接使用返回值。
並且您有正則表達式的所有可能性。 圖像例如,你想驗證每個名字的名字是以「先生/女士名字姓氏,名稱標題」的形式出現。
當它變得棘手時是如果你只想允許某些範圍的unicode字符。
例如,如果你只想讓U + 0600-U + 06FF(1536-1791)(阿拉伯語)。加上一定範圍的丁丁和括號等等。
沒有預先定義的字符類,並定義它們不會那麼優雅。
在這種情況下,真的是最好的辦法是遍歷由字符的文本字符,並檢查範圍...
#1,使用ctype_alnum()
。它比正則表達式更快,你不必擔心你是否得到正確的正則表達式。我也覺得它很整潔。
下面是一個應該用於電子郵件驗證的工具。
以下是電子郵件地址的要求,與相關文獻:
/**
Validate an email address.
Provide email address (raw input)
Returns true if the email address has the email
address format and the domain exists.
*/
function validEmail($email)
{
$isValid = true;
$atIndex = strrpos($email, "@");
if (is_bool($atIndex) && !$atIndex)
{
$isValid = false;
}
else
{
$domain = substr($email, $atIndex+1);
$local = substr($email, 0, $atIndex);
$localLen = strlen($local);
$domainLen = strlen($domain);
if ($localLen < 1 || $localLen > 64)
{
// local part length exceeded
$isValid = false;
}
else if ($domainLen < 1 || $domainLen > 255)
{
// domain part length exceeded
$isValid = false;
}
else if ($local[0] == '.' || $local[$localLen-1] == '.')
{
// local part starts or ends with '.'
$isValid = false;
}
else if (preg_match('/\\.\\./', $local))
{
// local part has two consecutive dots
$isValid = false;
}
else if (!preg_match('/^[A-Za-z0-9\\-\\.]+$/', $domain))
{
// character not valid in domain part
$isValid = false;
}
else if (preg_match('/\\.\\./', $domain))
{
// domain part has two consecutive dots
$isValid = false;
}
else if
(!preg_match('/^(\\\\.|[A-Za-z0-9!#%&`_=\\/$\'*+?^{}|~.-])+$/',
str_replace("\\\\","",$local)))
{
// character not valid in local part unless
// local part is quoted
if (!preg_match('/^"(\\\\"|[^"])+"$/',
str_replace("\\\\","",$local)))
{
$isValid = false;
}
}
if ($isValid && !(checkdnsrr($domain,"MX") ||
?checkdnsrr($domain,"A")))
{
// domain not found in DNS
$isValid = false;
}
}
return $isValid;
}
來源:道格拉斯·洛弗爾
它充滿了語法錯誤,例如'$ domainLen 255' – Gordon 2010-10-16 13:01:53
我的不好;由於某種原因,編輯刪除了「小於」和「大於」之間的所有內容。糾正。 – 2010-10-16 13:41:40
到目前爲止,我所看到的最好的電子郵件驗證(注:它還會檢查電子郵件域):
/**
* Validates an email address to RFC 3696 specification.
* @source http://www.linuxjournal.com/article/9585
* @param string $email_address Email address (raw input)
* @return <type> Returns true if the email address has the email address
* format and the domain exists.
*/
public static function email($email_address) {
if (empty($email_address)) return $email_address;
$is_valid = true;
$atIndex = strrpos($email_address, "@");
if (is_bool($atIndex) && !$atIndex) {
throw new VerificationException('The email address ('.$email_address.') does not contain an @ symbol');
$is_valid = false;
}
else {
$domain = substr($email_address, $atIndex+1);
$local = substr($email_address, 0, $atIndex);
$local_length = strlen($local);
$domain_length = strlen($domain);
if ($local_length < 1 || $local_length > 64) {
// Local part length exceeded
throw new VerificationException('The email address ('.$email_address.') local part exceeds maximum length');
} else if ($domain_length < 1) {
// Domain missing
throw new VerificationException('The email address ('.$email_address.') is mising the domain part');
} else if ($domain_length > 255) {
// Domain part length exceeded
throw new VerificationException('The email address ('.$email_address.') domain exceeds maximum length');
} else if ($local[0] == '.' || $local[$local_length-1] == '.') {
// Local part starts or ends with '.'
throw new VerificationException('The email address ('.$email_address.') local part can not end with a dot (.)');
} else if (preg_match('/\\.\\./', $local)) {
// Local part has two consecutive dots
throw new VerificationException('The email address ('.$email_address.') local part can not contain two consecutive dots (..)');
} else if (!preg_match('/^[A-Za-z0-9\\-\\.]+$/', $domain)) {
// Character not valid in domain part
throw new VerificationException('The email address ('.$email_address.') domain contains invalid characters');
} else if (preg_match('/\\.\\./', $domain)) {
// Domain part has two consecutive dots
throw new VerificationException('The email address ('.$email_address.') domain can not contain two consecutive dots (..)');
} else if (!preg_match('/^(\\\\.|[A-Za-z0-9!#%&`_=\\/$\'*+?^{}|~.-])+$/', str_replace("\\\\","",$local))) {
// Character not valid in local part unless
// Local part is quoted
if (!preg_match('/^"(\\\\"|[^"])+"$/',
str_replace("\\\\","",$local))) {
throw new VerificationException('The email address ('.$email_address.') contains invalid (non excaped) characters');
}
}
if ($is_valid && !(checkdnsrr($domain, 'MX') || checkdnsrr($domain, 'A'))) {
// Domain not found in DNS
throw new VerificationException('The email address ('.$email_address.') domain could not be found with a DNS lookup');
}
}
return $email_address;
}
我很當然,問題1和問題3已經被充分回答了。 – Gordon 2010-10-16 23:57:03
他們有,但是例如從來沒有見過ctype_alnum()字母數字驗證,它總是正則表達式,每個答案是不同的,所以我想知道哪一個被認爲是最好的。 – 2010-10-17 17:21:53