2009-07-01 11 views
22

Ich habe eine URL-Zeichenfolge im folgenden Format.Konvertieren von & nach & in Objective-C

http://myserver.com/_layouts/feed.aspx?xsl=4&web=%2F&page=dda3fd10-c776-4d69-8c55-2f1c74b343e2&wp=476f174a-82df-4611-a3df-e13255d97533

Ich möchte & mit & in der obigen URL ersetzen. Mein Ergebnis sollte sein:

http://myserver.com/_layouts/feed.aspx?xsl=4&web=%2F&page=dda3fd10-c776-4d69-8c55-2f1c74b343e2&wp=476f174a-82df-4611-a3df-e13255d97533

mir jemand den Code schreiben kann dies zu tun bekommen?

Dank

Antwort

14
[urlString stringByReplacingOccurrencesOfString:@"&" withString:@"&"]; 
+0

ich das gleiche tat ... aber gibt es eine eingebaute Möglichkeit zu Mach das ... – nbojja

+2

@nbojja Wie viel mehr gebaut willst du? Wenn Sie daran interessiert sind, fügen Sie eine Methode, die dies als eine Kategorie in NSString tut und dann eingebaut ist. – Abizern

+10

@Abizern: Viele Sprachen haben eingebaute Methoden zum Enkodieren und Dekodieren von HTML-Entitäten, Obj-C fehlt diese und viele andere Dinge, die Programmierer seit 2002 für selbstverständlich halten. Suchen und Ersetzen ist ein schlechter Ersatz, weil man ziemlich lange brauchen wird, um zu wissen, dass man alle Entitäten bekommt. –

8

Es gibt keine integrierte Funktion für das im iPhone SDK. Sie sollten file a bug, dass Sie die Funktionalität möchten. Im normalen Mac OS X SDK können Sie das Fragment entweder in ein NSAttributedString als HTML laden und es bitten, eine einfache Zeichenfolge zurückzugeben, oder verwenden Sie CFXMLCreateStringByUnescapingEntities().

@interface NSString (LGAdditions) 
- (NSString *) stringByUnescapingEntities; 
@end 

@implementation NSString (LGAdditions) 
- (NSString *) stringByUnescapingEntities { 
    CFStringRef retvalCF = CFXMLCreateStringByUnescapingEntities(kCFAllocatorDefault, (CFStringRef)self, NULL); 
    return [NSMakeCollectable(retvalCF) autorelease]; 
} 
@end 
+0

Diese nicht mit automatischer Referenz funktioniert Counting (ARC) {Seufzer} – mpemburn

+0

@mpemburn haben Sie versuchen: 'CFStringRef retvalCF = CFXMLCreateStringByUnescapingEntities (kCFAllocatorDefault, (__bridge CFAllocatorRef) selbst, NULL); return (NSString *) CFBridgingRelease (retvalCF); ' –

+0

Es sollte nicht mit CFAllocatorRef, sondern mit CFStringRef überbrückt werden. Das war auch in der ursprünglichen Code-Liste falsch. – dgatwood

113

Überprüfen Sie meine NSString category for HTML. Hier sind die verfügbaren Methoden:

// Strips HTML tags & comments, removes extra whitespace and decodes HTML character entities. 
- (NSString *)stringByConvertingHTMLToPlainText; 

// Decode all HTML entities using GTM. 
- (NSString *)stringByDecodingHTMLEntities; 

// Encode all HTML entities using GTM. 
- (NSString *)stringByEncodingHTMLEntities; 

// Minimal unicode encoding will only cover characters from table 
// A.2.2 of http://www.w3.org/TR/xhtml1/dtds.html#a_dtd_Special_characters 
// which is what you want for a unicode encoded webpage. 
- (NSString *)stringByEncodingHTMLEntities:(BOOL)isUnicode; 

// Replace newlines with <br /> tags. 
- (NSString *)stringWithNewLinesAsBRs; 

// Remove newlines and white space from string. 
- (NSString *)stringByRemovingNewLinesAndWhitespace; 
+0

Danke dafür, Michael - sehr praktisch! (So ​​praktisch wie die Antwort auf diese Frage, die akzeptiert wurde, ist falsch!) –

+0

Kein Problem;) Freut mich, dass Sie es nützlich fanden! –

+0

Ja, sehr nützlich, danke Michael – Jack

4

Für iOS sollte der folgende Code für numerische Codes funktionieren. Es sollte relativ einfach sein, die gerne von &amp; zu erweitern ...

-(NSString*)unescapeHtmlCodes:(NSString*)input { 

NSRange rangeOfHTMLEntity = [input rangeOfString:@"&#"]; 
if(NSNotFound == rangeOfHTMLEntity.location) { 
    return input; 
} 


NSMutableString* answer = [[NSMutableString alloc] init]; 
[answer autorelease]; 

NSScanner* scanner = [NSScanner scannerWithString:input]; 
[scanner setCharactersToBeSkipped:nil]; // we want all white-space 

while(![scanner isAtEnd]) { 

    NSString* fragment; 
    [scanner scanUpToString:@"&#" intoString:&fragment]; 
    if(nil != fragment) { // e.g. '&#38; B' 
     [answer appendString:fragment];   
    } 

    if(![scanner isAtEnd]) { // implicitly we scanned to the next '&#' 

     int scanLocation = (int)[scanner scanLocation]; 
     [scanner setScanLocation:scanLocation+2]; // skip over '&#' 

     int htmlCode; 
     if([scanner scanInt:&htmlCode]) { 
      char c = htmlCode; 
      [answer appendFormat:@"%c", c]; 

      scanLocation = (int)[scanner scanLocation]; 
      [scanner setScanLocation:scanLocation+1]; // skip over ';' 

     } else { 
      // err ? 
     } 
    } 

} 

return answer; 

} 

Einige Unit-Test-Code ...

-(void)testUnescapeHtmlCodes { 

NSString* expected = @"A & B"; 
NSString* actual = [self unescapeHtmlCodes:@"A &#38; B"]; 
STAssertTrue([expected isEqualToString:actual], @"actual = %@", actual); 

expected = @"& B"; 
actual = [self unescapeHtmlCodes:@"&#38; B"];  
STAssertTrue([expected isEqualToString:actual], @"actual = %@", actual); 

expected = @"A &"; 
actual = [self unescapeHtmlCodes:@"A &#38;"]; 
STAssertTrue([expected isEqualToString:actual], @"actual = %@", actual); 

}