Что такое внутренняя функция детектора nsdata в iphone sdk - PullRequest
3 голосов
/ 30 декабря 2011

Я получил странные результаты, используя NSDataDetector, и я ищу понимание того, как это работает.

Соответствует ли оно внутренней базе данных или использует какой-либо алгоритм разделения для обнаружения отдельных полей в строке?

В настоящее время я использую следующий код для определения полей адреса:

NSDataDetector *address = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeAddress error:nil];
NSArray* matcheslinkaa = [address  matchesInString:inputString options:0 range:NSMakeRange(0, [inputString length])];
if ([matcheslinkaa count]>0) 
{
    for (NSTextCheckingResult *match in matcheslinkaa) 
    {
        if ([match resultType] == NSTextCheckingTypeAddress) 
        {
            NSDictionary *phoneNumber = [match addressComponents];
            NSLog(@"addressComponents  %@",phoneNumber);
        }
    }
}

Ниже приведен пример набора входных строк и их соответствующих выходов с использованием приведенного выше кода:

inputString = @"100 Main Street\n"  
               "Anytown, NY 12345\n"
               "USA";
// prints:
// addressComponents  {
//     City = Anytown;
//     Country = USA;
//     State = NY;
//     Street = "100 Main Street";
//     ZIP = 12345;
// }

inputString = @"A-205 Natasha Golf View\n"
               "2 Inner Ring Road\n"
               "Bangalore\n"
               "560071\n"
               "Karnataka";
// prints:
// addressComponents  {
//     City = Bangalore;
//     Street = "2 Inner Ring Road";
//     ZIP = 560071;
// }

inputString = @"A-205 Natasha Golf View\n"
               "2 Inner Ring Road\n"
               "Domlur\n"
               "Bangalore\n"
               "560071\n"
               "India";

// prints:
// addressComponents  {
//     City = Bangalore;
//     Street = "2 Inner Ring Road";
//     ZIP = 560071;
// }

inputString = @"Dak Bhavan\n"
               "Parliament Street\n"
               "NEW DELHI 110001\n"
               "INDIA";

// => `addressComponents` is empty!

Как видите, у NSDataDetector нет проблем с извлечением адресов в США. Почему с индийскими адресами дела обстоят намного хуже, и даже название страны не найдено?

Ответы [ 2 ]

1 голос
/ 07 января 2012

Отказ

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

Основная причина, почему он лучше работает с американскими адресами, я полагаю, так же проста, как и скучна:

Apple - американская компания и (за исключением британца Джонатана Айва) каждый из ее топ-менеджеров является североамериканцем. Поэтому неудивительно, что их подход «сначала США / Северная Америка» [1].

Это причина, по которой конструкция силового блока настолько элегантна при использовании компактного разъема US (где складываются зубцы) - и выглядит так неуклюже, как почти любой другой ...

Другая причина в том, что Apple - как и все остальные - отправляет как можно скорее:
Если у них есть что-то, что работает для их клиентов в США, но не для остальных, почему бы не отправить его за им и добавить поддержку других языков через обновления программного обеспечения позже?

Что касается вашей проблемы, то, что может или может не помочь (читай: «Я не беспокоил тестирование») с обнаружением адресов, это то, что пользователь установил язык их устройства соответственно.

Если - и только если - вы обнаружите, что это положительно влияет на ваши результаты, вы можете проверить, равна ли страновая часть [[NSLocale currentLocale] localeIdentifier] IN и (если это не так) подсказать пользователю чтобы изменить это в приложении «Настройки», в противном случае.

Если это окажется бесполезным, вы должны Roll-Your-Own ™ ...


(1) Основным заметным исключением из этого правила стал выбор технологии основной полосы для исходного iPhone, где предпочтение GSM по сравнению с CDMA могло быть недостатком локально , но ключом к успеху глобально .

1 голос
/ 04 января 2012

Можете ли вы попробовать это.

[detector enumerateMatchesInString:str
                         options:0 
                           range:NSMakeRange(0, [str length]) 
                      usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {

            
                NSDictionary *phoneNumber = [result addressComponents];
                NSLog(@"addressComponents  %@",phoneNumber);
            

                      }];

Если это не работает для вас ... Адрес должен быть в формате

100 Main Street
Anytown, NY 12345
USA

, вы можете попробовать другиеальтернативы .. может быть путем преобразования вашего "str" ​​в вышеуказанный формат ...

или напрямую вы можете попробовать это ..

 NSArray *array = [tempAddrStr componentsSeparatedByString:@","];
        if([array count]>2)
        {
            NSString *str1 = [array objectAtIndex:[array count]-3];
            NSString *str2 = [array objectAtIndex:[array count]-2];
            str1=[str1 stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
            str1=[str1 stringByReplacingOccurrencesOfString:@"\n" withString:@" "];
            str2=[str2 stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
            str2=[str2 stringByReplacingOccurrencesOfString:@"\n" withString:@" "];

            tempAddrStr=[NSString stringWithFormat:@"%@, %@",str1,str2];
        }
        else if([tempAddrStr length]>=140&&[array count]>1)
        {
            NSString *str1 = [array objectAtIndex:[array count]-2];
            NSString *str2 = [array objectAtIndex:[array count]-1];
            str1=[str1 stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
            str1=[str1 stringByReplacingOccurrencesOfString:@"\n" withString:@" "];
            str2=[str2 stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
            str2=[str2 stringByReplacingOccurrencesOfString:@"\n" withString:@" "];

            tempAddrStr=[NSString stringWithFormat:@"%@, %@",str1,str2];
        }

Это часть кода из моего проектапросто получить штат и город по заданному адресу, возвращенному CLGeocoder.

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