Які найкращі практики для перевірки електронних адрес на iOS 2.0


167

Який найчистіший спосіб перевірити адресу електронної пошти, яку користувач вводить на iOS 2.0?

ПРИМІТКА . Це історичне запитання, яке є специфічним для iOS 2.0 і обумовлене його віком і тим, скільки інших питань пов'язано з ним, його не можна відкликати, і НЕ МОЖЕ бути змінено на "сучасне" питання.


Я шукаю рішення какао. Я розумію дійсність електронних листів та правила щодо перевірки електронних листів. Однак оскільки RegEx не є легко доступним на Cocoa Touch, я шукаю рішення Cocoa Touch для перевірки. Не перелік правил навколо перевірки.
Маркус С. Зарра

Поки найкраща пропозиція щодо коду, яку я знайшов, - це використання RegExKitLite та регулярні вирази. На щастя, це менш болісно, ​​ніж це звучить.
Маркус С. Зарра

Дивіться коментарі нижче щодо використання NSRegularExpression для додатків, що не підтримують os <4.0.
Беон

1
Оскільки це, мабуть, є канонічним питанням щодо перевірки адреси електронної пошти, має сенс оновити вдосконалені відповіді в міру дозрівання 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];
}

9
Чудово, але він не працює в ОС <3.0, оскільки NSPredicate недоступний.
Феліксиз

4
Приємно. Всі забувають, що NSPredicate може запускати регулярні виразки.
Rog

5
Це один дуже поганий реггекс. Наприклад, це не вдасться людям, які використовують верхній домен .museum. Зверніться до цієї статті: linuxjournal.com/article/9585
Jonny

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
leanne

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 році, вона все ще залишається дуже високою в результатах пошуку. Я просто хотів додати, що це більше не актуально, і вищевказаний регекс трохи обмежує. наприклад, тепер у вас може бути чотиризначний або більше домен верхнього рівня
Джек

Хороший момент, відредагувавши його на "принаймні 2 цифри". Не соромтесь редагувати подальші зміни, якщо хочете.
Брендон Ярбро

7

Хоча зосередженість на регулярних виразах хороша, але це лише перший і необхідний крок. Є й інші кроки, які також потрібно враховувати для гарної стратегії перевірки.

Дві речі на моїй голові:

  1. Перевірка DNS, щоб переконатися, що домен насправді існує.

  2. Після dns перевірки ви також можете зробити перевірку smtp. надішліть дзвінок на сервер smtp, щоб побачити, чи дійсно користувач існує.

Таким чином ви можете вловлювати всілякі помилки користувачів і переконатися, що це дійсний електронний лист.


7

Ця функція проста, але при цьому більш ретельно перевіряє електронну адресу. Наприклад, згідно з RFC2822, адреса електронної пошти не повинна містити два періоди поспіль, наприклад, ім'я..іменне ім'я @ домен..com

Також важливо використовувати якорі в регулярних виразах, як це видно в цій функції. Без прив’язок наступна адреса електронної пошти вважається дійсною: ім'я) прізвище lastname@domain.com (бла, оскільки розділ lastname@domain.com є дійсним, ігноруючи перше; ім'я) на початку та (бла в кінці. Якіри примушують система регулярних виразів для перевірки всієї електронної пошти.

Ця функція використовує 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. У нас є останній os, який є ios 7.1. ви також можете використовувати ios 6.
Гаурав Гілані

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. 

4

Я виявив, що використання регулярного виразу працює досить добре для підтвердження адреси електронної пошти.

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

Ось посилання на хороше джерело, http://www.regular-expressions.info/email.html .


Нещодавно я реалізував другий на цій сторінці, і я цілком задоволений цим. Це чудово працює для простої електронної адреси user@host.com, без лапок та дужок для повного імені. Відмінно підходить для перевірки веб-форм, коли люди ні в якому разі не набирають такого роду.
зомбат

2
Бідні люди зі своїм .museum TLD.
BadPirate

3

Викопавши бруд, але я просто натрапив на SHEmailValidator, який робить ідеальну роботу та має приємний інтерфейс.


Це питання стосувалося iOS 2.0, у якому не було NSPredicate або цілого ряду інших речей, які використовуються в цій бібліотеці.
Маркус С. Зарра

1
Я знаю, але я спершу приземлився тут під час пошуку "перевірки електронної пошти ios". Можливо, хтось із майбутніх мене здійснить той самий пошук і приземлиться тут, і це заощадить йому деякий час.
Кирила

1

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

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

Крім цього, придбайте останнє видання книги O'Reilly Освоєння регулярних виразів. Ви хочете витратити час, щоб зрозуміти перші 3 або 4 глави. Все після цього буде будувати експертизу щодо оптимізованого використання RegEx.

Часто ряд менших, простіших у керуванні RegExes простіше у обслуговуванні та налагодженні.


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


На NSPredicateiOS 2.0 не було
Marcus S. Zarra

-2

Не варто намагатися використовувати регулярний вимір для перевірки електронної пошти. З постійно змінюваними TLD, ваш валідатор є неповним або неточним. Натомість слід використовувати NSDataDetectorбібліотеки Apple, які займуть рядок, і спробувати перевірити, чи є якісь відомі поля даних (електронні листи, адреси, дати тощо). Apple SDK зробить важкий підйом, щоб бути в курсі TLDs, і ви зможете відмовитись від їхніх зусиль !! :)

Крім того, якщо 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

BTW, 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.
Маркус С. Зарра
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.