Nano Hash - криптовалюты, майнинг, программирование

Проверка электронной почты с помощью NSDataDetector

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

NSString *string = sourceNode.label; //coming from server

//Phone number
NSDataDetector *phoneDetector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypePhoneNumber error:nil]; 
NSArray *phoneMatches = [phoneDetector matchesInString:string options:0 range:NSMakeRange(0, [string length])];

for (NSTextCheckingResult *match in phoneMatches) {

    if ([match resultType] == NSTextCheckingTypePhoneNumber) {
        NSString *matchingStringPhone = [match description];
        NSLog(@"found URL: %@", matchingStringPhone);
    }
}  

Но как сделать то же самое для электронной почты?


  • Вам не повезло, нет NSTextCheckingType для электронной почты, вы можете попробовать NSTextCheckingTypeLink, но это может не дать желаемых результатов. 13.01.2012
  • разве нельзя было бы вместо этого использовать регулярное выражение? developer.apple.com/library/mac /#документация/Фонд/ 13.01.2012
  • Возможно, тогда регулярное выражение - единственный вариант, который не учитывается. Или есть что-то еще, что я могу сделать? 13.01.2012
  • Здесь есть реальное решение вашего вопроса: stackoverflow.com/q/15525117/1633251 21.03.2013

Ответы:


1

В документации Apple кажется, что распознанные типы не включают электронную почту: http://developer.apple.com/library/IOs/#documentation/AppKit/Reference/NSTextCheckingResult_Class/Reference/Reference.html#//apple_ref/c/tdef/NSTextCheckingType

Поэтому я предлагаю вам использовать регулярное выражение. Это было бы так:

NSString* pattern = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]+";

NSPredicate* predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", pattern];
if ([predicate evaluateWithObject:@"[email protected]"] == YES) {
  // Okay
} else {
  // Not found
}

ИЗМЕНИТЬ:

Поскольку @dunforget получил лучшее решение, несмотря на то, что мое решение принято, пожалуйста, прочитайте его ответ.

13.01.2012
  • -1 должен быть за плохие ответы или глупые. Может быть, этот ответ не самый лучший и умный, но он работает. 09.12.2013

  • 2
    if (result.resultType == NSTextCheckingTypeLink)
    {
        if ([result.URL.scheme.locaseString isEqualToString:@"mailto"])
        {
            // email link
        }
        else
        {
            // url
        }
    }
    

    Адрес электронной почты попадает в NSTextCheckingTypeLink. Просто найдите «mailto:» в найденном URL-адресе, и вы узнаете, что это адрес электронной почты или URL-адрес.

    18.07.2013
  • Вместо проверки absoluteString было бы безопаснее сделать [match.URL.scheme isEqualToString:@"mailto"] 16.05.2014
  • Будьте осторожны, проверка только на mailtoabsoluteString или scheme) приведет к большому количеству ложных срабатываний. Детектор данных преобразует [email protected],[email protected] только в mailto:[email protected] и будет отображаться как совпадение, когда фактическая полная строка не является совпадением, поскольку в ней есть 2 адреса. Похоже на [email protected]{whitespace}. Полный ответ см. на stackoverflow.com/a/35076728/144857. 07.10.2016

  • 3

    Попробуйте следующий код, посмотрите, работает ли он для вас:

    NSString * mail = [email protected]
    NSDataDetector * dataDetector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeLink error:nil];
    NSTextCheckingResult * firstMatch = [dataDetector firstMatchInString:mail options:0 range:NSMakeRange(0, [mail length])];
    BOOL result = [firstMatch.URL isKindOfClass:[NSURL class]] && [firstMatch.URL.scheme isEqualToString:@"mailto"];
    
    30.08.2012
  • Хорошая идея, но у этого есть пара проблем. Он проверяет только первое совпадение — в строке может быть несколько совпадений, включая ссылки других типов. Кроме того, такие строки, как mailto:[email protected], также будут пропущены. 27.11.2012
  • Я думаю, что это лучший ответ на вопрос, вопрос требует сделать это с помощью dataDetectors, а не искать его альтернативу. 16.10.2015

  • 4

    Вот чистая версия Swift.

    extension String {
        func isValidEmail() -> Bool {
            guard !self.lowercaseString.hasPrefix("mailto:") else { return false }
            guard let emailDetector = try? NSDataDetector(types: NSTextCheckingType.Link.rawValue) else { return false }
            let matches = emailDetector.matchesInString(self, options: NSMatchingOptions.Anchored, range: NSRange(location: 0, length: self.characters.count))
            guard matches.count == 1 else { return false }
            return matches[0].URL?.absoluteString == "mailto:\(self)"
        }
    }
    

    Версия Swift 3.0:

    extension String {
        func isValidEmail() -> Bool {
            guard !self.lowercased().hasPrefix("mailto:") else { return false }
            guard let emailDetector = try? NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue) else { return false }
            let matches = emailDetector.matches(in: self, options: NSRegularExpression.MatchingOptions.anchored, range: NSRange(location: 0, length: self.characters.count))
            guard matches.count == 1 else { return false }
            return matches[0].url?.absoluteString == "mailto:\(self)"
        }
    }
    

    Цель-C:

    @implementation NSString (EmailValidator)
    
    - (BOOL)isValidEmail {
        if ([self.lowercaseString hasPrefix:@"mailto:"]) { return NO; }
    
        NSDataDetector* dataDetector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeLink error:nil];
        if (dataDetector == nil) { return NO; }
    
        NSArray* matches = [dataDetector matchesInString:self options:NSMatchingAnchored range:NSMakeRange(0, [self length])];
        if (matches.count != 1) { return NO; }
    
        NSTextCheckingResult* match = [matches firstObject];
        return match.resultType == NSTextCheckingTypeLink && [match.URL.absoluteString isEqualToString:[NSString stringWithFormat:@"mailto:%@", self]];
    }
    
    @end
    
    29.01.2016
  • Это не работает из-за guard matches.count == 1 else { return false } 05.10.2016
  • @laynemoseley не уверен, в чем проблема с этим утверждением guard. В основном это гарантирует, что у вас есть элемент в matches, иначе matches[0] выйдет из строя. И если count › 1, ваша строка также не будет действительным адресом электронной почты. 05.10.2016
  • о, знаешь что, ты прав. Я неправильно разобрал эту логику. Спасибо за разъяснения! 07.10.2016
  • Почему у тебя ! on line guard !self.lowercased().hasPrefix(mailto:) else { return false } 08.01.2017
  • @RyanHeitner, потому что, если в начале строки есть mailto:, то полная строка не является допустимым адресом электронной почты, но детектор данных правильно извлечет адрес электронной почты из остальной части строки, ложно создавая впечатление, что полная строка является действующий адрес. (Вы не хотите пытаться отправить электронное письмо по адресу mailto:[email protected] или сохранить его в базе данных и т. д. 08.01.2017
  • @DaveWood Разве нельзя отбросить guard matches.count == 1 else { return false } и изменить последнюю строку на return matches.first?.url?.absoluteString == "mailto:\(self)"? Поскольку в любом случае он уже является необязательным для URL-адреса. 28.03.2017
  • Это определяет адрес электронной почты[email protected] как действительный адрес электронной почты. Согласно RFC 5322 (3.2.3 - стр. 13) использование нескольких точек не допускается. .. 29.11.2017

  • 5

    Кажется, детектор теперь работает для электронной почты?

    let types = [NSTextCheckingType.Link, NSTextCheckingType.PhoneNumber] as NSTextCheckingType
    responseAttributedLabel.enabledTextCheckingTypes = types.rawValue
    

    И я могу нажимать на электронные письма. Однако я использую TTTAttributedLabel.

    20.10.2016

    6

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

    func isEmail(emailString : String)->Bool {
    
        // need optional - will be nil if successful
        var error : NSError?
    
        // use countElements() with Swift 1.1
        var textRange = NSMakeRange(0, count(emailString))
    
        // Link type includes email (mailto)
        var detector : NSDataDetector = NSDataDetector(types: NSTextCheckingType.Link.rawValue, error: &error)!
    
        if error == nil {
    
        // options value is ignored for this method, but still required! 
        var result = detector.firstMatchInString(emailString, options: NSMatchingOptions.Anchored, range: textRange)
    
            if result != nil {
    
                // check range to make sure a substring was not detected
                return result!.URL!.scheme! == "mailto" && (result!.range.location == textRange.location) && (result!.range.length == textRange.length)
    
            }
    
        } else {
    
            // handle error
        }
    
        return false
    }
    
    let validEmail = isEmail("[email protected]") // returns true
    
    14.02.2015
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

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

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

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..