NSScanner Loop Question - PullRequest
       9

NSScanner Loop Question

2 голосов
/ 12 июня 2011

У меня есть объект NSScanner, который просматривает HTML-документы на наличие тегов абзаца.Кажется, что сканер останавливается на первом найденном результате, но мне нужны все результаты в массиве.

Как улучшить мой код, чтобы просмотреть весь документ?

- (NSArray *)getParagraphs:(NSString *) html 
{
    NSScanner *theScanner;
    NSString *text = nil;

    theScanner = [NSScanner scannerWithString: html];

    NSMutableArray*paragraphs = [[NSMutableArray alloc] init];

    // find start of tag
    [theScanner scanUpToString: @"<p>" intoString: NULL];
    if ([theScanner isAtEnd] == NO) {
        NSInteger newLoc = [theScanner scanLocation] + 10;
        [theScanner setScanLocation: newLoc];

        // find end of tag
        [theScanner scanUpToString: @"</p>" intoString: &text];

        [paragraphs addObject:text];
    }

    return text;
}

Ответы [ 2 ]

6 голосов
/ 13 июня 2011

Не используйте сканер для разбора HTML (и не используйте регулярные выражения, либо .... о, боль) *. Весь смысл HTML в том, что это структурированный документ, который предназначен для обхода в виде дерева узлов или объекта. Практически вся отрасль, основанная на DOM [Document Object Model], построена на этом.

Просто используйте синтаксический анализатор XML, поскольку [хорошо структурированный HTML в любом случае действительно является XML]. NSXMLDocument (или - если вам нужно управлять событиями - NSXMLParser ) будет работать великолепно.

Или, если вам приходится иметь дело с искаженным HTML (то есть с произвольной канализацией сервера), используйте подходящий анализатор HTML.

Этот вопрос / ответ описывает именно это , с убедительным примером.

* Не говоря уже о том, что анализ HTML - это «решенная проблема» в отрасли. Нет необходимости бросать новый.

2 голосов
/ 12 июня 2011

Отказ от ответственности: Для анализа HTML лучше использовать анализатор HTML, такой как анализатор HTML 4 в libxml, особенно для работы с произвольным, возможно, искаженным HTML.В любом случае, поскольку вопрос состоит в том, как улучшить существующий код, используя NSParser, я приведу следующий пример.Это будет работать в большинстве случаев, но в некоторых случаях это не так.Для серьезного разбора HTML используйте анализатор HTML.


Повторяйте, пока сканер не исчерпал все символы:

NSScanner* scanner = [NSScanner scannerWithString:html];
NSMutableArray *paragraphs = [[NSMutableArray alloc] init];
[scanner scanUpToString:@"<p" intoString:nil];
while (![scanner isAtEnd]) {
    [scanner scanUpToString:@">" intoString:nil];
    [scanner scanString:@">" intoString:nil];
    NSString * text = nil;
    [scanner scanUpToString:@"</p>" intoString:&text];
    if (text) { // if html contains empty paragraphs <p></p>, text could be nil
        [paragraphs addObject:text];
    }
    [scanner scanUpToString:@"<p" intoString:nil];
}
...
[paragraphs release];
...