2009-07-01 42 views
22

Tôi có chuỗi URL ở định dạng sau.Chuyển đổi & sang & trong Mục tiêu-C

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

Tôi muốn thay thế & với & trong URL trên. Kết quả của tôi nên là:

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

Ai đó có thể gửi cho tôi đoạn code để thực hiện điều này?

Cảm ơn

Trả lời

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

tôi đã làm như vậy ... nhưng là có cách nào để BUILTIN làm điều này ... – nbojja

+2

@nbojja Bạn muốn xây dựng bao nhiêu hơn? Nếu bạn lo lắng, hãy thêm một phương thức thực hiện điều này làm một danh mục trên NSString và sau đó nó được tích hợp. – Abizern

+10

@Abizern: Nhiều ngôn ngữ có các phương thức mã hóa và giải mã các thực thể HTML, Obj-C thiếu điều này và nhiều những điều lập trình viên cho phép từ năm 2002. Tìm kiếm và thay thế là một thay thế nghèo nàn, bởi vì bạn sẽ phải dành một chút thời gian để biết bạn có được tất cả các thực thể. –

8

Không có tích hợp chức năng cho điều này trong iPhone SDK. Bạn nên file a bug mà bạn muốn có chức năng. Trong Mac OS X SDK bình thường, bạn có thể tải đoạn mã vào một mã HTML NSAttributedString và yêu cầu nó quay lại một chuỗi đơn giản hoặc sử dụng 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

Điều này không hoạt động với tính năng Tự động tham khảo Đếm (ARC) {sigh} – mpemburn

+0

@mpemburn bạn đã thử: 'CFStringRef retvalCF = CFXMLCreateStringByUnescapingEntities (kCFAllocatorDefault, (__bridge CFAllocatorRef) self, NULL); return (NSString *) CFBridgingRelease (retvalCF); ' –

+0

Nó không nên được bắc cầu đến CFAllocatorRef, mà đúng hơn là CFStringRef. Điều đó cũng sai trong danh sách mã ban đầu. – dgatwood

113

Kiểm tra NSString category for HTML của tôi. Dưới đây là các phương pháp có sẵn:

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

Cảm ơn vì điều này, Michael - rất tiện dụng! (Tiện dụng như câu trả lời cho câu hỏi này đã được chấp nhận là sai!) –

+0

Không vấn đề gì;) Rất vui khi bạn thấy nó hữu ích! –

+0

Có, rất hữu ích, cảm ơn Michael – Jack

4

Đối với iOS, mã sau sẽ hoạt động đối với mã số. Nó phải là tương đối dễ dàng để mở rộng đến những cái tên như &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; 

} 

Một số mã đơn vị kiểm tra ...

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

}