Как извлечь список строк электронной почты или почтового ящика в тексте или проверить, соответствует ли строка правильному адресу электронной почты?

Учитывая некоторый произвольный текст, я хотел бы извлечь все адреса электронной почты и «спецификаторы почтовых ящиков» (например, "Fred Smith" <[email protected]> ). Я смотрел NSDataDetector, но он не обрабатывал адреса электронной почты.

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

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

Регулярные выражения, показанные на этом сайте, отформатированы для PHP и имеют ведущие и конечные маркеры «/», а также «флаги», указывающие на отсутствие регистра и т. Д. (См. Этот сайт для получения дополнительной информации), поэтому их необходимо удалить перед использованием выражения в проекте Objective-C. Кроме того, любые якоря нуждаются в зачистке, так как мы хотим, чтобы несколько адресов были не только одним (т.е. «^» и «$»).

NSRegularExpression – это класс, который можно использовать здесь. То, что я нашел полезным, – это сохранить регулярное выражение в файле в моем проекте, так что вам не нужно беспокоиться об исключении всех обратных косых черт и котировок. Затем код считывает выражение в строку и создает объект следующим образом:

 NSString *fullPath = [[NSBundle mainBundle] pathForResource:self.regex ofType:@"txt"]; NSString *pattern = [NSString stringWithContentsOfFile:fullPath encoding:NSUTF8StringEncoding error:NULL]; __autoreleasing NSError *error = nil; reg = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:&error]; // some patterns may not need NSRegularExpressionCaseInsensitive assert(reg && !error); 

После того как вы получили инициализированное выражение, вы используете его для возврата списка диапазонов, каждый из которых является адресом:

 NSArray *ret = [reg matchesInString:str options:0 range:NSMakeRange(0, [str length])]; 

Тем не менее, мы знаем, что все адреса электронной почты содержат один «@», поэтому, вероятно, стоит проверить, что строка имеет хотя бы одну перед ее обработкой. Кроме того, поскольку в тексте может отображаться строка и / или каретка, вы можете сначала удалить их. Скорее всего, лучше снять их полностью, так как какая-то почтовая программа могла бы разделить линию на какую-то внутреннюю точку адреса.

Когда у вас есть список диапазонов адресов, то по большей части задание выполняется – если все, что вам нужно, – это адрес. Однако часто адреса представлены в формате «спецификатор почтового ящика», где имя добавляется к адресу и адрес, заключенный в «<» и «>». Этот формат описан в RFC5322 в разделе 3.4.

Чтобы восстановить имя из «спецификатора почтового ящика», проверьте, не упакован ли адрес с «<» и «>», и если это так, найдите строку, предшествующую «<», игнорируя пробел (пока вы не найдете первый персонаж). Большинство имен будут заключены в двойные кавычки (обычная практика), но на самом деле это могут быть голой буквенно-цифровой строки с использованием обратного слэша, чтобы включить пробел или другие специальные символы (например, «»).

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

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

EDIT1: для более быстрого, но менее строгого метода см. Комментарий CodaFi.

EDIT2: похоже, что содержимое URL-адреса mailto: может быть довольно сложным, проект github обрабатывает только самые простые и не кодирует адрес. Это будет рассмотрено в будущем обновлении.

EDIT3: проект был обновлен, чтобы полностью обрабатывать объекты mailto :, и возвращается в, cc, bcc, subject и body, все URLdecoded.

  • Розетки с Swift
  • Как вы отпустите MTAudioProcessingTap?
  • Обеспечивает ли @synchronized гарантии безопасности потоков или нет?
  • Как найти ошибки, которые метод может бросить и поймать в Swift
  • CFHTTPMessageAddAuthentication не удается добавить данные аутентификации для запроса
  • Почему мое SSL-подтверждение не выполняется перед отправкой каких-либо сообщений SSL?
  • Возможность подключения VPN с клиента к tunnel_server (с использованием приложения SimpleTunnel от Apple), но неспособной просматривать Интернет на устройстве
  • Xcode 9: сбой в работе с сжатой транзакцией
  • параметры конфигурации, такие как «-extra-cflags» - я смущен
  • Как передать структуру Anyobject в Swift 2?
  • Самый эффективный способ скопировать файл с GCD?
  • Давайте будем гением компьютера.