NSRegularExpression Regex NSP Предикат только с HTML <a> в <div>

Я хотел бы получить конкретные данные в JSON Data: все ссылки в href в этой разметке <div id='gallery-1'

Например с моими данными JSON:

<p><strong style=\"font-size: 13px;\">22nd March</strong></p>\n
<p>Swell is 3 foot and clean but wind swing south west later. Get on the early</p>\n
<p><span id=\"more-113\"></span></p>\n
<p>High tide: 1922 2.6m    <span style=\"color: #ff0000;\"> <a href=\"http://www.bundoransurfco.com/webcam/\">
<strong>CLICK HERE FOR LIVE PEAK WEBCAM</strong></a></span></p>\n
<p>Low Tide: 1249 -0.1m</p>\n<p><b>3 day forecast to March 23rd</b></p>\n
<p>Looks like a fun few days with light winds and a long period swell.</p>\n\n\t\t
<style type='text/css'>\n\t\t\t#gallery-1 {\n\t\t\t\tmargin: auto;\n\t\t\t}\n\t\t\t
#gallery-1 .gallery-item {\n\t\t\t\tfloat: left;\n\t\t\t\tmargin-top: 10px;\n\t\t\t\t
text-align: center;\n\t\t\t\twidth: 50%;\n\t\t\t}\n\t\t\t#gallery-1 img {\n\t\t\t\t
border: 2px solid #cfcfcf;\n\t\t\t}\n\t\t\t
#gallery-1 .gallery-caption {\n\t\t\t\t
margin-left: 0;\n\t\t\t}\n\t\t\t
/* see gallery_shortcode() in wp-includes/media.php */\n\t\t</style>\n\t\t
<div id='gallery-1' class='gallery galleryid-113 gallery-columns-2 gallery-size-medium'>
<dl class='gallery-item'>\n\t\t\t<dt class='gallery-icon portrait'>\n\t\t\t\t
<a rel=\"prettyPhoto[gallery-113]\" href='http://www.bundoransurfco.com/wp-content/uploads/2014/11/10411096_10152611456607000_886839954460588268_n.jpg'>
<img width=\"225\" height=\"300\" src=\"http://www.bundoransurfco.com/wp-content/uploads/2014/11/10411096_10152611456607000_886839954460588268_n-225x300.jpg\" 
class=\"attachment-medium colorbox-113 \" alt=\"10411096_10152611456607000_886839954460588268_n\" /></a>\n\t\t\t
</dt></dl>\n\t\t\t
<br style='clear: both' />\n\t\t</div>\n\n
<p><a href=\"http://www.bundoransurfco.com/webcam/\"> </a></p>\n
<h1> Wind Charts</h1>\n<p><a href=\"http://www.windguru.cz/int/index.php?sc=103244\">
<img class=\"size-thumbnail wp-image-747 alignleft\" title=\"wind guru\" src=\"http://www.bundoransurfco.com/wp-content/uploads/2010/12/wind-guru-67x68.jpg\" alt=\"\" width=\"67\" height=\"68\" /></a> <a href=\"http://www.xcweather.co.uk/\"><img class=\"alignnone size-thumbnail wp-image-749\" title=\"xcweathersmall\" src=\"http://www.bundoransurfco.com/wp-content/uploads/2010/12/xcweathersmall2-67x68.jpg\" alt=\"\" width=\"67\" height=\"68\" /></a>       <a href=\"http://www.buoyweather.com/wxnav6.jsp?region=UK&program=nww3BW1&grb=nww3&latitude=55.0&longitude=-8.75&zone=0&units=e\"><img class=\"alignnone size-thumbnail wp-image-750\" title=\"buoy weather\" src=\"http://www.bundoransurfco.com/wp-content/uploads/2010/12/buoy-weather-67x68.jpg\" alt=\"\" width=\"67\" height=\"68\" /></a> <a href=\"http://www.windguru.cz/int/index.php?sc=103244\">Wind Guru</a>       <a href=\"http://www.xcweather.co.uk/\">XC Weather</a>       <a href=\"http://www.buoyweather.com/wxnav6.jsp?region=UK&program=nww3BW1&grb=nww3&latitude=55.0&longitude=-8.75&zone=0&units=e\">Buoy Weather</a></p>\n<h1>Swell Charts</h1>\n<p><a href=\"http://magicseaweed.com/Bundoran-Surf-Report/50/\"><img class=\"alignnone size-thumbnail wp-image-753\" title=\"msw logo\" src=\"http://www.bundoransurfco.com/wp-content/uploads/2010/12/msw-logo-67x43.jpg\" alt=\"\" width=\"75\" height=\"43\" /></a>             <a href=\"http://magicseaweed.com/UK-Ireland-MSW-Surf-Charts/1/\"><img class=\"alignnone size-thumbnail wp-image-754\" title=\"magicseaweedwamchart\" src=\"http://www.bundoransurfco.com/wp-content/uploads/2010/12/magicseaweedwamchart1-67x68.png\" alt=\"\" width=\"67\" height=\"68\" /></a>       <a href=\"http://www.marine.ie/Home/site-area/data-services/marine-forecasts/wave-forecasts\"><img class=\"alignnone wp-image-755 size-thumbnail\" title=\"marine institute irish bouy data\" src=\"http://www.bundoransurfco.com/wp-content/uploads/2010/12/marine-institute-irish-bouy-data-67x42.jpg\" alt=\"\" width=\"67\" height=\"42\" /></a>                 <a href=\"http://magicseaweed.com/Bundoran-Surf-Report/50/\">Magic Seaweed</a>      <a href=\"http://magicseaweed.com/UK-Ireland-MSW-Surf-Charts/1/\">MSM WAM</a>          <a href=\"http://www.marine.ie/Home/site-area/data-services/marine-forecasts/wave-forecasts\">Marine Institute</a></p>\n<h1>Pressure, Weather, Tides</h1>\n<p><a href=\"http://news.bbc.co.uk/weather/forecast/13000\"><img class=\"alignnone size-thumbnail wp-image-756\" title=\"bbc pressure\" src=\"http://www.bundoransurfco.com/wp-content/uploads/2010/12/bbc-pressure-67x68.jpg\" alt=\"\" width=\"67\" height=\"68\" /></a>          <a href=\"http://www.met.ie/\"><img class=\"alignnone size-thumbnail wp-image-759\" title=\"met eireann\" src=\"http://www.bundoransurfco.com/wp-content/uploads/2010/12/met-eireann-67x68.jpg\" alt=\"\" width=\"67\" height=\"68\" /></a>            <a href=\"http://news.bbc.co.uk/weather/forecast/13000\">BBC Pressure</a>      <a href=\"http://www.met.ie/\">Met Eireann</a>      <a href=\"http://www.irishtimes.com/weather/tides.html\">Irish Tide Tables</a></p>\n

Выбрать только: http://www.bundoransurfco.com/wp-content/uploads/2014/11/10411096_10152611456607000_886839954460588268_n.jpg

Я могу получить каждый <a> содержащий href (NSLog(@"%@", url);), мой NSPredicate не работает, но мне действительно нужен только href в <div id='gallery-1'...

Вот мой код:

#pragma mark - Regex <a href=http://.........>
        NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"<a[^>]*>" options:NSRegularExpressionCaseInsensitive error:nil];
        NSArray *arrayOfAllMatches = [regex matchesInString:stringBDD options:0 range:NSMakeRange(0, [stringBDD length])];

        NSMutableArray *arrayOfURLs = [[NSMutableArray alloc] init];
        for (NSTextCheckingResult *match in arrayOfAllMatches) {
            NSString* substringForMatch = [stringBDD substringWithRange:match.range];
            [arrayOfURLs addObject:substringForMatch];
        }

#pragma mark - NSPredicate
        NSArray *url = [NSArray arrayWithArray:arrayOfURLs];
        NSLog(@"%@", url);
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF beginswith[c] %@", @"<a href='http://www.bundoransurfco.com/wp-content/uploads/"];
        NSArray *arrayPictures = [url filteredArrayUsingPredicate:predicate];
        NSLog(@"%@", arrayPictures);

#pragma mark - Count number of pictures find
        NSUInteger count = 0, length = [stringBDD length];
        NSRange range = NSMakeRange(0, length);
        while(range.location != NSNotFound)
        {
            range = [stringBDD rangeOfString: @"<a href='http://www.bundoransurfco.com/wp-content/uploads/" options:0 range:range];
            if(range.location != NSNotFound)
            {
                range = NSMakeRange(range.location + range.length, length - (range.location + range.length));
                count++;
            }
        }
        NSLog(@"%zd", count);

ОБНОВИТЬ:

NSURL *url = [NSURL URLWithString:@"http://www.bundoransurfco.com/surf-report/surf-report/?json=1"];
if (url)
{
    NSData * urlDataToParse = [NSData dataWithContentsOfURL:url];
    TFHpple * parser = [TFHpple hppleWithHTMLData:urlDataToParse];
    NSArray * ahrefNodes = [parser searchWithXPathQuery:@"//a[@href]"]; //array of all <a href> and <iframe>
    NSLog(@"%@", ahrefNodes);
}

Это дает мне много контента, а не только <a href >...

NSURL *url = [NSURL URLWithString:@"http://www.bundoransurfco.com/surf-report/surf-report/?json=1"];
if (url)
{
    NSData * urlDataToParse = [NSData dataWithContentsOfURL:url];
    TFHpple * parser = [TFHpple hppleWithHTMLData:urlDataToParse];
    NSArray * ahrefNodes = [parser searchWithXPathQuery:@"//div[@id='gallery-1']"]; //array of all <a href> and <iframe>
    NSLog(@"%@", ahrefNodes);
}

Не работает:/

1 ответ

Вы можете сделать это намного проще для себя, используя Hpple. Он может анализировать HTML в соответствии с соглашением XPath (потому что, очевидно, вы не должны анализировать HTML напрямую).

Например, у меня есть метод, который проверяет действительный URL. И после этого я запрашиваю контент, используя Hpple для всех <a> а также <iframe> теги, указывающие, что я хочу только значения href а также src свойства этих тегов:

if (url)
{
     NSData * urlDataToParse = [NSData dataWithContentsOfURL:url];
     TFHpple * parser = [TFHpple hppleWithHTMLData:urlDataToParse];
     NSArray * ahrefNodes = [parser searchWithXPathQuery:@"//a[@href]|//iframe[@src]"]; //array of all <a href> and <iframe>
}

NSArray возвращаются значения, которые следуют <a href=... а также <iframe src=..., Я бы проверил репозиторий, на который я ссылался, но ваш поисковый запрос выглядит так @"//div[@id]", Вы также можете найти эту ссылку полезной.

Некоторые обновления:

Используйте запрос XPath, который я перечислил (@"//div[@id]"), указав название id тег, который вы хотите, не будет работать из-за всех ваших дополнительных escape-последовательностей.

Я получил полные результаты, используя следующее:

- (void)viewDidLoad {
    [super viewDidLoad];

    NSURL * sampleDataURL = [[NSBundle mainBundle] URLForResource:@"surfSample" withExtension:@"json"]; // I created this by just copy/pasting your provided "json" into a file and giving it a .json extension
    NSData * sampleData = [NSData dataWithContentsOfURL:sampleDataURL];

    TFHpple * dataParser = [TFHpple hppleWithData:sampleData isXML:NO];
    NSArray * nodes = [dataParser searchWithXPathQuery:@"//div[@id]"];

    for (TFHppleElement * elementNode in nodes) {
        NSLog(@"The element: %@", elementNode);
    }
}

Как я пишу в своем комментарии выше, результаты очень грязные. См. Pastebin: http://pastebin.com/DpfDKcmp

Тем не менее, очистка строки escape-символов намного проще, чем использование регулярных выражений и предикатов, поэтому вам будет проще достичь своей цели. (Имеется в виду, либо получить содержимое как фактический JSON, либо преобразовать его в строку и использовать что-то вроде stringByReplacingOccurrencesOfString:withString:)

Другие вопросы по тегам