2011-04-17 43 views
1

我想從許多不同形式的HTML中去除圖像URL。使用NSRegularExpression從圖像數據中剝離URL

我有這個已經:

NSRegularExpression *regex = [[NSRegularExpression alloc] 
initWithPattern:@"(?<=img src=\").*?(?=\")" 
options:NSRegularExpressionCaseInsensitive error:nil]; 

如果HTML像<img src="someurl.jpg" alt="" .../>形成這工作得很好,但是這並非總是如此,有時也有src這是不挑先於其他屬性向上。

+1

您無法使用正則表達式正確解析HTML。 – Till 2011-04-17 13:41:56

回答

5

對於正則表達式來說,這是一件困難的事情。使用XMLParser和XPath通常會更好。但是,如果HTML不是非常有效(即使使用TidyHTML),您可以發現XPath不能很好地工作。

如果你必須尋找使用正則表達式的圖像,我建議是這樣的:

<\\s*?img\\s+[^>]*?\\s*src\\s*=\\s*([\"\'])((\\\\?+.)*?)\\1[^>]*?> 

因此,假設您在使用相同名稱的字符串有rawHTML,用途:

NSRegularExpression* regex = [[NSRegularExpression alloc] initWithPattern:@"<\\s*?img\\s+[^>]*?\\s*src\\s*=\\s*([\"\'])((\\\\?+.)*?)\\1[^>]*?>" options:NSRegularExpressionCaseInsensitive error:nil]; 
NSArray *imagesHTML = [regex matchesInString:rawHTML options:0 range:NSMakeRange(0, [rawHTML length])]; 
[regex release]; 

如果你想從源頭中得到實際的圖像URL,然後我會使用類似的東西(運行在前一個正則表達式的輸出上):

(?i)\\b((?:[a-z][\\w-]+:(?:/{1,3}|[a-z0-9%])|www\\d{0,3}[.]|[a-z0-9.\\-]+[.][a-z]{2,4}/)(?:[^\\s()<>]+|\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\))+(?:\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\)|[^\\s`!()\\[\\]{};:'\".,<>?«»「」‘’] 

是的,我知道,瘋了!但你確實問過:-)

Credit:那最終的正則表達式是從John Gruber/Daring Fireball

這是我過去寫的一些代碼,它返回一個NSString url的圖像。我嘗試使用它(作爲最後的手段)從非常簡單的HTML中獲取圖像URL:

- (NSArray *)extractSuitableImagesFromRawHTMLEntry:(NSString *)rawHTML { 
NSMutableArray *images = [[NSMutableArray alloc] init]; 

if(rawHTML!=nil&&[rawHTML length]!=0) { 
    NSRegularExpression* regex = [[NSRegularExpression alloc] initWithPattern:@"<\\s*?img\\s+[^>]*?\\s*src\\s*=\\s*([\"\'])((\\\\?+.)*?)\\1[^>]*?>" options:NSRegularExpressionCaseInsensitive error:nil]; 
    NSArray *imagesHTML = [regex matchesInString:rawHTML options:0 range:NSMakeRange(0, [rawHTML length])]; 
    [regex release]; 

    for (NSTextCheckingResult *image in imagesHTML) { 
     NSString *imageHTML = [rawHTML substringWithRange:image.range]; 

     NSRegularExpression* regex2 = [[NSRegularExpression alloc] initWithPattern:@"(?i)\\b((?:[a-z][\\w-]+:(?:/{1,3}|[a-z0-9%])|www\\d{0,3}[.]|[a-z0-9.\\-]+[.][a-z]{2,4}/)(?:[^\\s()<>]+|\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\))+(?:\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\)|[^\\s`!()\\[\\]{};:'\".,<>?«»「」‘’]))" options:NSRegularExpressionCaseInsensitive error:nil]; 
     NSArray *imageSource=[regex2 matchesInString:imageHTML options:0 range:NSMakeRange(0, [imageHTML length])]; 
     [regex2 release]; 

     NSString *imageSourceURLString=nil; 
     for (NSTextCheckingResult *result in imageSource) { 
      NSString *str=[imageHTML substringWithRange:result.range]; 
      //DebugLog(@"url is %@",str); 
      if([str hasPrefix:@"http"]) { 
       //strip off any crap after file extension 
       //find jpg 
       NSRange r1=[str rangeOfString:@".jpg" options:NSBackwardsSearch&&NSCaseInsensitiveSearch]; 
       if(r1.location==NSNotFound) { 
        //find jpeg 
        NSRange r2=[str rangeOfString:@".jpeg" options:NSBackwardsSearch&&NSCaseInsensitiveSearch]; 
        if(r2.location==NSNotFound) { 
         //find png 
         NSRange r3=[str rangeOfString:@".png" options:NSBackwardsSearch&&NSCaseInsensitiveSearch]; 
         if(r3.location==NSNotFound) { 
          break; 
         } else { 
          imageSourceURLString=[str substringWithRange:NSMakeRange(0, r3.location+r3.length)]; 
         } 
        } else { 
         //jpeg was found 
         imageSourceURLString=[str substringWithRange:NSMakeRange(0, r2.location+r2.length)]; 
         break; 
        } 
       } else { 
        //jpg was found 
        imageSourceURLString=[str substringWithRange:NSMakeRange(0, r1.location+r1.length)]; 
        break; 
       } 
      } 
     } 

     if(imageSourceURLString==nil) { 
      //DebugLog(@"No image found."); 
     } else { 
      DebugLog(@"*** image found: %@", imageSourceURLString); 
      NSURL *imageURL=[NSURL URLWithString:imageSourceURLString]; 
      if(imageURL!=nil) { 
       [images addObject:imageURL]; 
      } 
     } 
    } 
} 
    return [images autorelease]; 
} 
+0

所有正則表達式都被轉義用於NSString – Damien 2011-04-18 11:05:25