2010-12-29 3 views
1

Ich versuche, einen Algorithmus zu finden, URLs in einem Textkörper zu finden. Im Moment habe ich den folgenden Code (das war mein Hinsetzen und es heraushacken Code, und ich weiß, dass es einen besseren Weg, muss sein):Verbessern Algorithmus zum Suchen von URLs in einem Textkörper - obj-c

statusText.text = @"http://google.com http://www.apple.com www.joshholat.com"; 

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

NSRange currentLocation = NSMakeRange(0, statusText.text.length); 
for (int x = 0; x < statusText.text.length; x++) { 
    currentLocation = [[statusText.text substringFromIndex:(x + currentLocation.location)] rangeOfString:@"http://"]; 
    if (currentLocation.location > statusText.text.length) break; 
    [urlLocations addObject:[NSNumber numberWithInt:(currentLocation.location + x)]]; 
} 
currentLocation = NSMakeRange(0, statusText.text.length); 
for (int x = 0; x < statusText.text.length; x++) { 
    currentLocation = [[statusText.text substringFromIndex:(x + currentLocation.location)] rangeOfString:@"http://www."]; 
    if (currentLocation.location > statusText.text.length) break; 
    [urlLocations addObject:[NSNumber numberWithInt:(currentLocation.location + x)]]; 
} 
currentLocation = NSMakeRange(0, statusText.text.length); 
for (int x = 0; x < statusText.text.length; x++) { 
    currentLocation = [[statusText.text substringFromIndex:(x + currentLocation.location)] rangeOfString:@" www." options:NSLiteralSearch]; 
    if (currentLocation.location > statusText.text.length) break; 
    [urlLocations addObject:[NSNumber numberWithInt:(currentLocation.location + 1 + x)]]; 
} 

//Get rid of any duplicate locations 
NSSet *uniqueElements = [NSSet setWithArray:urlLocations]; 
[urlLocations release]; 
NSArray *finalURLLocations = [[NSArray alloc] init]; 
finalURLLocations = [uniqueElements allObjects]; 

//Parse out the URLs of each of the locations 
for (int x = 0; x < [finalURLLocations count]; x++) { 
    NSRange temp = [[statusText.text substringFromIndex:[[finalURLLocations objectAtIndex:x] intValue]] rangeOfString:@" "]; 
    int length = temp.location + [[finalURLLocations objectAtIndex:x] intValue]; 
    if (temp.location > statusText.text.length) length = statusText.text.length; 
    length = length - [[finalURLLocations objectAtIndex:x] intValue]; 
    NSLog(@"URL: %@", [statusText.text substringWithRange:NSMakeRange([[finalURLLocations objectAtIndex:x] intValue], length)]); 
} 

Ich fühle mich wie es über die Verwendung von regulären Ausdrücken verbessert werden könnte oder so. Jede Hilfe bei der Verbesserung wäre sehr willkommen.

Antwort

5

Wenn Sie iOS 4.0+ Ziel, sollten Sie lassen Apple für Sie die Arbeit tun und nutzen die integrierte Datendetektoren. Erstellen Sie eine Instanz von NSDataDetector mit der Option NSTextCheckingTypeLink, und führen Sie sie über Ihre Zeichenfolge aus. Die documentation for NSDataDetector hat einige gute Beispiele für die Verwendung der Klasse.

Wenn Sie nicht/keine Daten Detektoren aus irgendeinem Grund verwenden, John Gruber vor ein gutes RegexMuster für URLs ein paar Monate Erkennung geschrieben hat: http://daringfireball.net/2010/07/improved_regex_for_matching_urls

+0

Ich kam hierher, um die genaue Regex-Link zu posten. – extremeboredom

+0

NSDataDetector war genau das was ich gesucht habe, danke eine Tonne dafür! Ich konnte meinen Algorithmus auf 10 Zeilen Code reduzieren. Ich wusste nicht einmal, dass es existiert. – joshholat

1

So wie ein Follow-up, ist hier, was mein Code wurde geändert in:

statusText.text = @"http://google.com http://www.apple.com www.joshholat.com hey there google.com"; 

NSError *error = NULL; 
NSDataDetector *detector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeLink error:&error]; 

NSArray *matches = [detector matchesInString:statusText.text 
            options:0 
             range:NSMakeRange(0, statusText.text.length)]; 

for (NSTextCheckingResult *match in matches) { 
    if ([match resultType] == NSTextCheckingTypeLink) { 
     NSLog(@"URL: %@", [[match URL] absoluteURL]); 
    } 
} 
Verwandte Themen