2009-07-01 8 views
22

J'ai une chaîne d'URL dans le format suivant.Conversion & en & dans Objective-C

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

Je veux remplacer & avec & dans l'URL ci-dessus. Mon résultat devrait être:

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

que quelqu'un peut me poster le code pour y parvenir?

Merci

Répondre

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

je fait la même chose ... mais est-il possible de builtin faites ceci ... – nbojja

+2

@nbojja Combien de plus construit voulez-vous? Si vous êtes concerné, ajoutez une méthode qui fait cela en tant que catégorie sur NSString, puis elle est intégrée. – Abizern

+10

@Abizern: Beaucoup de langages ont des méthodes intégrées pour encoder et décoder les entités HTML, Obj-C en manque et beaucoup d'autres Les choses que les programmeurs tiennent pour acquises depuis 2002. La recherche et le remplacement sont un mauvais substitut, parce que vous devrez passer un certain temps à savoir que vous obtenez toutes les entités. –

8

Il n'y a pas fonction intégrée pour cela dans le SDK iPhone. Vous devriez file a bug que vous voulez la fonctionnalité. Dans le SDK Mac OS X normal, vous pouvez soit charger le fragment dans un NSAttributedString au format HTML et lui demander de rendre une chaîne normale, soit utiliser 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

Cela ne fonctionne pas avec Automatic Reference Counting (ARC) {soupir} – mpemburn

+0

@mpemburn avez-vous essayé: 'CFStringRef retvalCF = CFXMLCreateStringByUnescapingEntities (kCFAllocatorDefault, (__bridge CFAllocatorRef) self, NULL); return (NSString *) CFBridgingRelease (retvalCF); ' –

+0

Il ne doit pas être lié à CFAllocatorRef, mais plutôt CFStringRef. C'était faux dans la liste de code d'origine, aussi. – dgatwood

113

Consultez mon NSString category for HTML. Voici les méthodes disponibles:

// 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

Merci pour cela, Michael - très pratique! (Aussi pratique que la réponse à cette question qui a été acceptée est fausse!) –

+0

Aucun problème;) Content que cela vous soit utile! –

+0

Oui, très utile, merci Michael – Jack

4

Pour iOS, le code suivant devrait fonctionner pour les codes numériques. Il devrait être relativement facile d'étendre aux goûts de &amp; ...

-(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; 

} 

Une partie du code de test d'unité ...

-(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); 

}