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

Учитывая некоторый произвольный текст, я хотел бы извлечь все адреса электронной почты и «спецификаторы почтовых ящиков» (например, "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.

  • Карфаген: Поддержка библиотечных специфических подмодулей?
  • Использование nm (1) для отображения символов из объектного файла, созданного для arm64 на OS X
  • iOS Core Audio: преобразование между kAudioFormatFlagsCanonical и kAudioFormatFlagsAudioUnitCanonical
  • Мониторинг iBeacon с помощью Mac?
  • Может ли Float32 когда-либо быть равным float в Objective-C?
  • Что такое предупреждение Apple в документации ARC, оставьте ссылку на ссылку?
  • Предупреждения о специфических статических рамах Xcode 7
  • как обрабатывать ключевые события в iphone
  • Как передать функцию object-c как обратный вызов функции C?
  • contentize и contentOffset в представлении NSScroll
  • Как перечислить ключи CFProperyList / CFDictionary
  • Давайте будем гением компьютера.