Мнение эксперта о проверке строки? - PullRequest
0 голосов
/ 16 октября 2010

Я мог бы спросить эти 3 отдельно, но решил объединить их.

Я хотел бы спросить мнение эксперта с примерами:

  1. как правильно проверить буквенно-цифровую строку? (только латинские буквы и цифры)

  2. как правильно проверить написанную строку юникода? (как и выше, но разрешены любые буквы стран)

  3. как правильно проверить, что строка выглядит как электронная почта? Я догадываюсь лучше всего это filter_var($string,FILTER_VALIDATE_EMAIL) (я думаю, это одинаково для URL и IP)

Спасибо.

Ответы [ 6 ]

2 голосов
/ 16 октября 2010

Для № 1 используйте ctype_alnum(). Это быстрее, чем регулярное выражение, и вам не нужно беспокоиться, если вы правильно поняли регулярное выражение. Я также думаю, что это намного аккуратнее.

0 голосов
/ 16 октября 2010

Лучшая проверка электронной почты, которую я видел до сих пор (примечание: она также проверяет домен электронной почты):

/**
 * 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;
}
0 голосов
/ 16 октября 2010

Вот тот, который должен работать для проверки электронной почты.

Ниже приведены требования к адресу электронной почты с соответствующими ссылками:

  1. Адрес электронной почты состоит излокальная часть и домен, разделенные знаком (@) (RFC 2822 3.4.1).
  2. Локальная часть может состоять из букв и цифр, а также следующих символов:!, #, $,%, &, ', *, +, -, /, =,?, ^, _, `, {, |,} и ~, возможно, с разделителями точек (.), внутри, но не в начале, в конце или в следующемк другому разделителю точек (RFC 2822 3.2.4).
  3. Локальная часть может состоять из строки в кавычках, то есть в кавычках ("), включая пробелы (RFC 2822 3.2.5).
  4. Пары в кавычках (например, \ @) являются допустимыми компонентами локальной части, хотя устарела форма из RFC 822 (RFC 2822 4.4).
  5. Максимальная длина локальной части составляет 64 символа (RFC 2821 4.5.3.1).
  6. Домен состоит из меток, разделенных точечными разделителями (RFC1035 2.3.1).
  7. Метки домена начинаются с буквенного символа, за которым следуют ноль или более буквенных символов, цифровых символов или дефиса (-), заканчивая буквенным или цифровым символом (RFC 1035 2.3.1).
  8. Максимальноедлина метки составляет 63 символа (RFC 1035 2.3.1).
  9. Максимальная длина домена составляет 255 символов (RFC 2821 4.5.3.1).
    1. Домен должен быть полностью определен и разрешен для записи адреса DNS типа A или MX (RFC 2821 3.6).


     /**
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;
}


Источник: Дуглас Ловелл

0 голосов
/ 16 октября 2010

filter_very аккуратный и эффективный для специальных целей, но также ограниченный.

вы также получаете только отфильтрованную возвращаемую строку, которую нужно сравнить с исходной строкой, чтобы увидеть, подходит ли она.

кроме разрешенных символов могут быть определенные требования и / или структуры, которые вы не можете проверить таким способом.

наиболее распространенный способ - использовать функции pcre и особенно preg_match.это очень эффективно, и вы можете напрямую работать с возвращаемым значением.

и у вас есть все возможности регулярных выражений.Например, вы хотите проверить, чтобы каждое встречающееся имя находилось в форме exacmt «Mr / Mrs Firstname Lastname, akademic-title».

, когда сложно, если вы хотите разрешить только определенные диапазоны Юникодасимволов.

например, если вы хотите разрешить только U + 0600 – U + 06FF (1536–1791) (арабский).плюс определенный диапазон дингбатов и скобок или что-то в этом роде.

для этого нет предопределенных классов символов, и их определение будет не таким уж элегантным.

в этом случае лучшим способом действительно будетзацикливание текста за символом и проверка диапазонов ...

0 голосов
/ 16 октября 2010
  1. preg_match('/[a-zA-Z0-9]+/', $str)
  2. Что-то с этим Я думаю
0 голосов
/ 16 октября 2010

Вы, вероятно, хотите использовать регулярные выражения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...