使用NSRegularExpression从图像数据中删除URL

时间:2011-04-17 04:50:50

标签: iphone objective-c

我想从许多不同格式的HTML中删除图像网址。

我已经有了这个:

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

如果HTML形成为<img src="someurl.jpg" alt="" .../>,这样可以正常工作,但情况并非总是如此,有时在src之前还有其他属性没有提取。

1 个答案:

答案 0 :(得分: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`!()\\[\\]{};:'\".,<>?«»“”‘’]
是的,我知道,疯了!但你确实问过: - )

信用:最终的正则表达式来自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];
}