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

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

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


person Marcus S. Zarra    schedule 28.04.2009    source источник
comment
Я ищу раствор какао. Я понимаю действительность электронных писем и правила их проверки. Однако, поскольку RegEx не так легко доступен в Cocoa Touch, я ищу решение для проверки какао Touch. Это не список правил валидации.   -  person Marcus S. Zarra    schedule 29.04.2009
comment
Пока что лучший вариант кода, который я нашел, - это использование RegExKitLite и регулярных выражений. К счастью, это менее болезненно, чем кажется.   -  person Marcus S. Zarra    schedule 29.04.2009
comment
См. Комментарии ниже об использовании NSRegularExpression для приложений, не поддерживающих OS ‹4.0.   -  person beOn    schedule 27.02.2011
comment
Обратите внимание, что этот вопрос был задан в 2009 году, когда на iPhone не было NSRegularExpression.   -  person Marcus S. Zarra    schedule 06.03.2011
comment
Люди, использующие iOS 3.0, могут использовать NSPredicate; люди, использующие iOS 4.0, могут использовать NSRegularExpression.   -  person benzado    schedule 23.05.2011
comment
Поскольку это кажется каноническим вопросом относительно проверки адреса электронной почты, имеет смысл обновлять его с помощью улучшенных ответов по мере развития iOS. Имея это в виду, я добавил ответ, который использует NSDataDetector в iOS для проверки адресов электронной почты: stackoverflow.com/a/23547905/257550 < / а>   -  person memmons    schedule 08.05.2014
comment
Это канонический вопрос для iOS 2. NSDataDetector не существовало в iOS 2.   -  person Marcus S. Zarra    schedule 08.05.2014
comment
Этот вопрос кажется не по теме, потому что он касается iOS 2.0, которая устарела много лет назад.   -  person Nathan Eror    schedule 20.05.2014


Ответы (12)


Ответ на Использование регулярного выражения для проверки адреса электронной почты очень подробно объясняет, что грамматика, указанная в 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];
}
person catlan    schedule 19.07.2009
comment
Отлично, но не работает в OS ‹3.0, потому что NSPredicate недоступен. - person Felixyz; 13.10.2009
comment
Хороший. Все забывают, что NSPredicate может запускать регулярные выражения. - person Rog; 14.10.2009
comment
Это очень плохое регулярное выражение. Например, это не сработает для людей, использующих домен .museum top. См. Эту статью: linuxjournal.com/article/9585 - person Jonny; 27.08.2010
comment
Итак, помимо изменения конца на {2,6}, какие изменения можно было бы внести, чтобы значительно улучшить это регулярное выражение, чтобы оно работало в большинстве распространенных случаев? - person Tomas Andrle; 02.09.2010
comment
Более полное регулярное выражение можно найти на странице cocoawithlove.com/2009/. 06 /, который можно использовать вместо этого простого. - person Tomas Andrle; 02.09.2010
comment
Вот очень наивное, но либеральное регулярное выражение электронной почты в виде строки Какао: @"[^@]+@[^.@]+(\\.[^.@]+)+" Если вам нужно подтвердить адрес электронной почты, отправьте ему сообщение и посмотрите, удастся ли это. Вы никогда не сможете проверить это с каким-либо уровнем точности с помощью одного только регулярного выражения, поэтому лучше не раздражать пользователей и не терять регистрации из-за излишне строгого регулярного выражения. - person Sami Samhuri; 13.09.2011
comment
А как насчет заглавных букв во втором регулярном выражении? - person Jakob; 13.05.2013
comment
Я бы добавил +1, если бы не все эти пробелы в объявлении метода: p. - person Kyle Clegg; 05.09.2013
comment
Похоже, он неправильно проверяет этот тип адреса: (email @ domain..ca). Я считаю, что это недействительный адрес электронной почты на основе RFC. - person Alexandre; 11.09.2013
comment
Первый позволяет использовать несколько (.), А второй - почти любые символы в домене. Применение обоих вместе дает точный результат. Спасибо :) +1 - person Baby Groot; 04.10.2013
comment
Мне также нужно удалить идентификатор электронной почты с номером, например [email protected]. - person venky; 29.01.2014
comment
Теперь есть TLD длиной более шести символов, например .international (13). - person nobody; 19.05.2014
comment
Что должна разрешить часть [a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]| \\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+ в конце? Он чередуется с последней десятичной группой IPv4-адреса, что довольно странно. - person nhahtdh; 29.09.2015
comment
Для тех, кто ищет совпадение без учета регистра, просто добавьте перед заданным регулярным выражением (?i). Для справки см. userguide.icu-project.org/strings/regexp. - person Leonid Usov; 26.04.2018

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

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

dtext           =       NO-WS-CTL /     ; Non white space controls

                        %d33-90 /       ; The rest of the US-ASCII
                        %d94-126        ;  characters not including "[",
                                        ;  "]", or "\"

Да, это означает, что +, 'и т. Д. Допустимы.

person Trey    schedule 28.04.2009
comment
По состоянию на май 2016 г .: RFC5322, раздел 3.4.1 - person leanne; 03.05.2016

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

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

person Marcus S. Zarra    schedule 29.04.2009
comment
NSPredicate может выполнять RegEx без добавления дополнительных библиотек в ваш проект. - person BadPirate; 03.09.2010
comment
Этот вопрос с апреля 2009 года был задан до того, как NSPredicate появился на iOS. - person Marcus S. Zarra; 04.09.2010
comment
Опять же, NSRegularExpression НЕ СУЩЕСТВОВАЛ в iOS 2.0, когда был задан этот вопрос. - person Marcus S. Zarra; 06.03.2011
comment
@Marcus, суть Stack Overflow не в том, чтобы вести историческую запись того, как конкретные проблемы решались в прошлом. Тем не менее, я отредактировал ваш вопрос, чтобы подчеркнуть угол совместимости 2.0. - person benzado; 23.05.2011
comment
Это мертвый вопрос, на который есть ответ. Спасибо за ваше мнение о том, что такое ТАК. - person Marcus S. Zarra; 25.05.2011
comment
Думаю, это неправильный ответ. На данный момент лучший ответ - это катлан ​​(и количество +1 только подтверждает это). - person Fmessina; 02.12.2012
comment
Пожалуйста, прочтите заголовок, это для iOS 2.0, для которой не существовало решения Catlan. - person Marcus S. Zarra; 03.12.2012

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

99% адресов электронной почты выглядят так: [email protected] или [email protected]

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

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

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

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

person Brandon Yarbrough    schedule 28.04.2009
comment
Несмотря на то, что этот ответ был написан в 2009 году, он по-прежнему занимает очень высокие позиции в результатах поиска. Я просто хотел добавить, что это уже не актуально, а указанное выше регулярное выражение немного ограничивает. например, теперь у вас может быть 4-значный или более домен верхнего уровня - person Jack; 06.08.2015
comment
Хороший момент, отредактировал его минимум на 2 цифры. Не стесняйтесь редактировать дальше, если хотите. - person Brandon Yarbrough; 06.08.2015

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

В голове у меня две вещи:

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

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

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

person Srikar Doddi    schedule 28.04.2009

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

Также важно использовать якоря в регулярных выражениях, как показано в этой функции. Без якорей допустимым считается следующий адрес электронной почты: first; name) [email protected] (blah, потому что раздел [email protected] действителен, игнорируется 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.

person Geek    schedule 15.10.2013
comment
В iOS 2.0 не было NSPredicate. - person Marcus S. Zarra; 15.10.2013
comment
Но какой толк в этом вопросе и в чем польза от ios 2. У нас установлена ​​последняя версия операционной системы, то есть ios 7.1. вы также можете использовать ios 6. - person Gaurav Gilani; 20.05.2014

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

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

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

person Paul Redman    schedule 28.04.2009
comment
Я недавно реализовал на этой странице предпоследнюю версию, и она мне очень нравится. Он отлично работает с простым адресом электронной почты [email protected], без кавычек или скобок для полного имени. Отлично подходит для проверки веб-форм, когда люди в любом случае не будут вводить такие вещи. - person zombat; 29.04.2009
comment
Бедные люди с их TLD .museum. - person BadPirate; 03.09.2010

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

person Cyrille    schedule 15.11.2013
comment
Этот вопрос был специфичен для iOS 2.0, в которой не было NSPredicate или целого ряда других вещей, которые используются в этой библиотеке. - person Marcus S. Zarra; 15.11.2013
comment
Я знаю, но я приземлился здесь первым, когда искал проверку электронной почты ios. Может быть, какой-нибудь будущий я проведу такие же поиски и приземлюсь здесь, и это сэкономит ему время. - person Cyrille; 16.11.2013

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

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

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

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

person user656483    schedule 12.03.2011

Вот расширение 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

person InnisBrendan    schedule 16.02.2017
comment
На iOS 2.0 не было NSPredicate - person Marcus S. Zarra; 17.02.2017

Вы не должны пытаться использовать регулярное выражение для проверки электронной почты. При постоянном изменении TLD ваш валидатор либо неполный, либо неточный. Вместо этого вам следует использовать NSDataDetector библиотеки Apple, которые будут брать строку и пытаться увидеть, есть ли какие-либо известные поля данных (электронные письма, адреса, даты и т. Д.). SDK от Apple сделает тяжелую работу по поддержанию актуальности 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)"
    }
}
person Mr. T    schedule 05.09.2017
comment
Этот вопрос был задан ВОСЕМЬ лет назад. - person Marcus S. Zarra; 06.09.2017
comment
И все же, если вы погуглите validate email objective-c, этот вопрос будет третьим результатом. Некоторые вещи в Интернете не стареют. :-) - person Craig Otis; 06.09.2017
comment
Пожалуйста, прекратите спамить ссылками на этот ответ под каждым сообщением, которое вы можете найти, которое связано с проверкой адресов электронной почты. Комментарии предназначены для получения разъяснений, а не для рассылки спама по ссылкам на ваши ответы. - person meagar; 09.09.2017
comment
Кстати, NSDataDetector НЕ существовало в iOS 2.0, о чем и был этот вопрос. - person Marcus S. Zarra; 13.09.2017

person    schedule
comment
Эта ветка / вопрос для iOS 2. NSPredicate не существует в iOS 2; он не был добавлен до iOS 3. - person Marcus S. Zarra; 19.05.2014
comment
Я ответил, потому что ваш ответ неправильный. Вопрос в том, как сделать X на iOS Y, и вы ответили фреймворком, которого нет в этой версии iOS. - person Marcus S. Zarra; 21.05.2014