Каковы лучшие практики для проверки адресов электронной почты на iOS 2.0

167

Какой самый чистый способ проверки адреса электронной почты, который пользователь вводит в iOS 2.0?

ПРИМЕЧАНИЕ . Это исторический вопрос, характерный для iOS 2.0, и из-за его возраста и количества других вопросов, связанных с ним, он не может быть удален и НЕ ДОЛЖЕН быть заменен на «современный» вопрос.

Маркус С. Зарра
источник
Я ищу решение какао. Я понимаю действительность писем и правила проверки писем. Однако, поскольку RegEx нелегко получить на Cocoa Touch, я ищу решение Cocoa Touch для проверки. Не список правил вокруг проверки.
Маркус С. Зарра
Пока лучшее предложение кода, которое я нашел, использует RegExKitLite и регулярные выражения. К счастью, это менее болезненно, чем кажется.
Маркус С. Зарра
См. Комментарии ниже об использовании NSRegularExpression для приложений, не поддерживающих os <4.0.
Веон
1
Поскольку это кажется каноническим вопросом, касающимся проверки адреса электронной почты, имеет смысл обновить его с улучшенными ответами по мере развития iOS. Имея это в виду, я добавил ответ, который использует iOS NSDataDetectorдля проверки адресов электронной почты: stackoverflow.com/a/23547905/257550
memmons
2
Этот вопрос кажется не по теме, потому что речь идет об iOS 2.0, которая устарела много лет назад.
Натан Эрор

Ответы:

354

Ответ на Использование регулярного выражения для проверки адреса электронной почты очень подробно объясняет, что грамматика, указанная в RFC 5322, слишком сложна для примитивных регулярных выражений.

Я рекомендую настоящий парсерный подход, такой как MKEmailAddress .

Как быстрое решение регулярных выражений увидеть эту модификацию DHValidation :

- (BOOL) validateEmail: (NSString *) candidate {
    NSString *emailRegex =
@"(?:[a-z0-9!#$%\\&'*+/=?\\^_`{|}~-]+(?:\\.[a-z0-9!#$%\\&'*+/=?\\^_`{|}"
@"~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\"
@"x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-"
@"z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5"
@"]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-"
@"9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21"
@"-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])"; 
    NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES[c] %@", emailRegex]; 

    return [emailTest evaluateWithObject:candidate];
}
catlan
источник
9
Отлично, но не работает на OS <3.0, потому что NSPredicate недоступен.
Феликсиз
4
Ницца. Все забывают, что NSPredicate может выполнять регулярные выражения.
Рог
5
Это очень плохое регулярное выражение. Например, это не удастся людям, использующим домен верхнего уровня .museum. См. Эту статью: linuxjournal.com/article/9585
Джонни
18
На сайте cocoawithlove.com/2009/06/ есть более полное регулярное выражение, которое можно использовать вместо этого простого.
Томас Андрле
12
Вот очень наивное, но либеральное регулярное выражение электронной почты в виде строки какао: @"[^@]+@[^.@]+(\\.[^.@]+)+"если вам нужно подтвердить адрес электронной почты, отправьте ему сообщение и посмотрите, получится ли это. Вы никогда не будете проверять это с какой-либо степенью точности с помощью одного регулярного выражения, поэтому лучше не злить пользователей и не терять регистрацию из-за излишне строгого регулярного выражения.
Сами Самхури
20

Прочитайте RFC. Почти каждый, кто думает, что знает, как разобрать / очистить / проверить адрес электронной почты, неправ.

http://tools.ietf.org/html/rfc2822 Раздел 3.4.1 очень полезен. уведомление

dtext = NO-WS-CTL /; Элементы управления без пробелов

                        % d33-90 /; Остальная часть США-ASCII
                        % d94-126; символы не включая «[»,
                                        ; "]", или "\"

Да, это означает, что +, 'и т. Д. Являются законными.

тройка
источник
Текущий по состоянию на май 2016 года: RFC5322, раздел 3.4.1
пост
17

Лучшее решение, которое я нашел до сих пор (и тем, на котором я остановился), - это добавить RegexKitLite в проект, который предоставляет доступ к регулярным выражениям через NSString Categories.

Добавлять в проект довольно безболезненно, и, как только он появится, любая логика проверки правильности электронной почты будет работать.

Маркус С. Зарра
источник
5
NSPredicate может выполнять RegEx без добавления дополнительных библиотек в ваш проект.
BadPirate
10
Этот вопрос с апреля 2009 года был до того, как NSPredicate существовал на iOS.
Маркус С. Зарра
7
Опять же, NSRegularExpression не существовало в iOS 2.0, когда был задан этот вопрос.
Маркус С. Зарра
9
@Marcus, смысл переполнения стека не в том, чтобы вести исторический отчет о том, как конкретные проблемы решались в прошлом. Тем не менее, я отредактировал ваш вопрос, чтобы подчеркнуть угол совместимости 2.0.
бензадо
2
Пожалуйста, прочтите заголовок, это для iOS 2.0, решения Catlan которого не было.
Маркус С. Зарра
10

Хорошее начало состоит в том, чтобы решить, что вы и не хотите принять в качестве адреса электронной почты?

99% адресов электронной почты выглядят так: bob.smith@foo.com или fred@bla.edu

Однако технически законно иметь адрес электронной почты, подобный этому: f !#$%&'*+-/=?^_{|} ~ "ha!" @ Com

Вероятно, в мире существует всего несколько действительных писем для доменов верхнего уровня, и почти никто не использует большинство этих других символов (особенно кавычки и обратные пометки), поэтому вы можете предположить, что это все недопустимые действия. Но вы должны сделать это как осознанное решение.

Кроме того, делайте то, что говорит Пол, и попытайтесь сопоставить ввод с регулярным выражением, например: ^ [A-Z0-9 ._% + -] + @ [A-Z0-9 .-] +. [AZ] { 2} $

Тот будет соответствовать почти каждому адресу электронной почты.

Брэндон Ярбро
источник
Несмотря на то, что этот ответ был написан в 2009 году, он по-прежнему очень высоко в результатах поиска Я просто хотел добавить, что это больше не актуально, и приведенное выше выражение немного ограничивает. например, теперь вы можете иметь 4-значный или более домен верхнего уровня
Джек
Хороший вопрос, отредактировал его как минимум 2 цифры. Не стесняйтесь редактировать дальше, если хотите.
Брэндон Ярбро
7

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

Две вещи на моей голове:

  1. Проверка DNS, чтобы убедиться, что домен действительно существует.

  2. После проверки DNS вы также можете выполнить проверку SMTP. отправьте вызов на сервер SMTP, чтобы узнать, существует ли пользователь на самом деле.

Таким образом, вы можете отследить все виды ошибок пользователя и убедиться, что это действительный адрес электронной почты.

Срикар Додди
источник
7

Эта функция проста, но проверяет адрес электронной почты более тщательно. Например, в соответствии с RFC2822 адрес электронной почты не должен содержать два периода подряд, например firstname..lastname @ domain..com

Также важно использовать якоря в регулярных выражениях, как видно из этой функции. Без привязок следующий адрес электронной почты считается действительным: first; name) lastname@domain.com (бла, потому что раздел lastname@domain.com действителен, игнорируя first; name) в начале и (blah в конце. механизм регулярных выражений для проверки всей электронной почты.

Эта функция использует NSPredicate, который не существует в iOS 2. К сожалению, он может не помочь спрашивающему, но, надеюсь, поможет другим с более новыми версиями iOS. Регулярные выражения в этой функции все еще могут быть применены к RegExKitLite в iOS 2, хотя. А для тех, кто использует iOS 4 или более позднюю версию, эти регулярные выражения могут быть реализованы с помощью NSRegularExpression.

- (BOOL)isValidEmail:(NSString *)email
{
    NSString *regex1 = @"\\A[a-z0-9]+([-._][a-z0-9]+)*@([a-z0-9]+(-[a-z0-9]+)*\\.)+[a-z]{2,4}\\z";
    NSString *regex2 = @"^(?=.{1,64}@.{4,64}$)(?=.{6,100}$).*";
    NSPredicate *test1 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex1];
    NSPredicate *test2 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex2];
    return [test1 evaluateWithObject:email] && [test2 evaluateWithObject:email];
}

См. Подтверждение адреса электронной почты с помощью регулярного выражения в Objective-C .

Фанат
источник
iOS 2.0 не имела NSPredicate.
Маркус С. Зарра
2
Но какова польза от этого вопроса и какая польза от ios 2. У нас установлена ​​последняя версия ОС ios 7.1. Вы также можете использовать ios 6.
Gaurav Gilani
6
NSString *emailString = textField.text; **// storing the entered email in a string.** 
**// Regular expression to checl the email format.** 
NSString *emailReg = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"; 
NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",emailReg]; 
if (([emailTest evaluateWithObject:emailString] != YES) || [emailStringisEqualToString:@""]) 
{ 
UIAlertView *loginalert = [[UIAlertView alloc] initWithTitle:@" Enter Email in" message:@"abc@example.com format" delegate:self 
cancelButtonTitle:@"OK" otherButtonTitles:nil]; 

enter code here

[loginalert show]; 
[loginalert release]; 
} 
If email is invalid, it will remind the user with an alert box. 
Hope this might be helpful for you all. 
hirak
источник
4

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

Конечно, основным недостатком регулярных выражений является удобство сопровождения, поэтому комментируйте так, как вы никогда раньше не комментировали. Я обещаю вам, если вы этого не сделаете, вы захотите, чтобы вы сделали, когда вы вернетесь к выражению через несколько недель.

Вот ссылка на источник хорошего, http://www.regular-expressions.info/email.html .

Пол Редман
источник
Я недавно применил второй на этой странице, и я вполне доволен этим. Он отлично работает для простого адреса электронной почты user@host.com, без кавычек или скобок для полного имени. Прекрасно работает для проверки веб-форм, когда люди не будут так печатать.
зомбат
2
Бедные люди с их доменом .museum.
BadPirate
3

Выкапывая грязь, но я просто наткнулся на SHEmailValidator, который отлично работает и имеет приятный интерфейс.

Сирил
источник
Этот вопрос был специфичен для iOS 2.0, в которой не было NSPredicate, или для множества других вещей, которые используются в этой библиотеке.
Маркус С. Зарра
1
Я знаю, но я приземлился здесь сначала при поиске «Проверка электронной почты IOS». Может быть, какое-то будущее я выполню тот же поиск и приземлюсь здесь, и это сэкономит ему время.
Сирил
1

Многие веб-сайты предоставляют RegExes, но вам стоит изучить и понять их, а также убедиться, что то, что вы хотите, чтобы это соответствовало вашим потребностям в рамках официального RFC для форматов адресов электронной почты.

Для изучения RegEx, интерпретируемые языки могут быть большим упрощением и испытательным стендом. Rubular построен на Ruby, но является хорошим быстрым способом тестирования и проверки: http://www.rubular.com/

Кроме того, купите последнее издание книги О'Рейли «Освоение регулярных выражений». Вы хотите потратить время, чтобы понять первые 3 или 4 главы. Все, что после этого будет основано на опыте высоко оптимизированного использования RegEx.

Часто серию небольших, более простых в управлении RegExes легче поддерживать и отлаживать.

user656483
источник
0

Вот расширение String, которое проверяет электронную почту в Swift.

extension String {

    func isValidEmail() -> Bool {
        let stricterFilter = false
        let stricterFilterString = "^[A-Z0-9a-z\\._%+-]+@([A-Za-z0-9-]+\\.)+[A-Za-z]{2,4}$"
        let laxString = "^.+@([A-Za-z0-9-]+\\.)+[A-Za-z]{2}[A-Za-z]*$"
        let emailRegex = stricterFilter ? stricterFilterString : laxString
        let emailTest = NSPredicate(format: "SELF MATCHES %@", emailRegex)
        return emailTest.evaluate(with: self)
    }
}

Скопировано из ответа на: Проверьте, что адрес электронной почты действителен на iOS

InnisBrendan
источник
На NSPredicateiOS 2.0 не было
Маркус С. Зарра
-2

Вы не должны пытаться использовать регулярные выражения для проверки электронной почты. С постоянно меняющимися TLD ваш валидатор является либо неполным, либо неточным. Вместо этого вы должны использовать NSDataDetectorбиблиотеки Apple, которые возьмут строку и попытаются увидеть, есть ли какие-либо известные поля данных (электронные письма, адреса, даты и т. Д.). Apple SDK сделает все возможное, чтобы идти в ногу с TLD, и вы сможете воспользоваться их усилиями !! :)

Кроме того, если iMessage (или любое другое текстовое поле) не считает, что это электронная почта, следует ли вам рассматривать электронную почту?

Я поместил эту функцию в NSStringкатегорию, поэтому строка, которую вы тестируете, является self.

- (BOOL)isValidEmail {
    // Trim whitespace first
    NSString *trimmedText = [self stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet];
    if (self && self.length > 0) return NO;

    NSError *error = nil;
    NSDataDetector *dataDetector = [[NSDataDetector alloc] initWithTypes:NSTextCheckingTypeLink error:&error];
    if (!dataDetector) return NO;

    // This string is a valid email only if iOS detects a mailto link out of the full string
    NSArray<NSTextCheckingResult *> *allMatches = [dataDetector matchesInString:trimmedText options:kNilOptions range:NSMakeRange(0, trimmedText.length)];
    if (error) return NO;
    return (allMatches.count == 1 && [[[allMatches.firstObject URL] absoluteString] isEqual:[NSString stringWithFormat:@"mailto:%@", self]]);
}

или как быстрое Stringрасширение

extension String {
    func isValidEmail() -> Bool {
        let trimmed = self.trimmingCharacters(in: .whitespacesAndNewlines)
        guard !trimmed.isEmpty, let dataDetector = try? NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue) else {
            return false
        }
        let allMatches = dataDetector.matches(in: trimmed, options: [], range: NSMakeRange(0, trimmed.characters.count))

        return allMatches.count == 1 && allMatches.first?.url?.absoluteString == "mailto:\(trimmed)"
    }
}
Мистер Т
источник
1
Этот вопрос из восьми лет назад.
Маркус С. Зарра
1
И все же, если вы Google validate email objective-c, этот вопрос является третьим результатом. Некоторые вещи в интернете не стареют. :-)
Крейг Отис
1
Пожалуйста, прекратите рассылать спам-ссылки на этот ответ ниже каждого поста, который вы можете найти, который связан с проверкой адресов электронной почты. Комментарии предназначены для запроса разъяснений, а не для спам-ссылок на ваши ответы.
Meagar
КСТАТИ, NSDataDetectorне существовало в iOS 2.0, о котором этот вопрос был / есть.
Маркус С. Зарра
-7
// Method Call
NSString *email = @"Your Email string..";

BOOL temp = [self validateEmail:email];

if(temp)
{
// Valid
}
else
{
// Not Valid
}
// Method description

- (BOOL) validateEmail: (NSString *) email {
    NSString *emailRegex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";
    NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex];
    BOOL isValid = [emailTest evaluateWithObject:email];
    return isValid;
}
Гаурав Гилани
источник
3
Эта тема / вопрос для iOS 2. NSPredicateне существовала в iOS 2; он не был добавлен до iOS 3.
Маркус С. Зарра
3
Я ответил, потому что ваш ответ неверен. Вопрос в том, «как вы делаете X на iOS Y», и вы ответили с помощью фреймворка, которого нет в этой версии iOS.
Маркус С. Зарра