NSRegularExpression для извлечения текста между двумя тегами XML

Как извлечь значение «6» между тегами «badgeCount» с помощью NSRegularExpression. Ниже приведен ответ от сервера:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><badgeCount>6</badgeCount><rank>2</rank><screenName>myName</screenName>

Ниже приведен код, который я пробовал, но не добился успеха. На самом деле он входит в другую часть и печатает «Значение регулярного выражения равно нулю»:

NSString *responseString =   [[NSString alloc] initWithBytes:[responseDataForCrntUser bytes] length:responseDataForCrntUser.length encoding:NSUTF8StringEncoding];

NSError *error;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(?<=badgeCount>)(?:[^])*?(?=</badgeCount)" options:0 error:&error];
if (regex != nil) {
    NSTextCheckingResult *firstMatch = [regex firstMatchInString:responseString options:0 range:NSMakeRange(0, [responseString length])];
    NSLog(@"NOT NIL");
    if (firstMatch) {
        NSRange accessTokenRange = [firstMatch rangeAtIndex:1];
        NSString *value = [urlString substringWithRange:accessTokenRange];
        NSLog(@"Value: %@", value);
    }
}
else
    NSLog(@"Value of regex is nil");

Если бы вы могли предоставить пример кода, который был бы очень признателен.

ПРИМЕЧАНИЕ. Я не хочу использовать NSXMLParser.


person Prazi    schedule 05.10.2011    source источник
comment
Почему вы не хотите использовать синтаксический анализатор xml для анализа xml?   -  person Mat    schedule 05.10.2011
comment
И что вы пробовали до сих пор?   -  person Mat    schedule 05.10.2011
comment
Нет необходимости в NSXMLParser для извлечения всего пары значений... Я получил необходимое регулярное выражение (?‹=badgeCount›)(?:[^])*?(?=‹/badgeCount), используя gskinner.com/RegExr онлайн-инструмент, но не может использовать то же выражение в NSRegular Expression...   -  person Prazi    schedule 05.10.2011
comment
Отредактируйте свой вопрос, включив в него код, который вы пробовали, и объясните, что именно в нем не работает.   -  person Mat    schedule 05.10.2011


Ответы (2)


Пример:

NSString *xml = @"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><badgeCount>6</badgeCount><rank>2</rank><screenName>myName</screenName>";
NSString *pattern = @"<badgeCount>(\\d+)</badgeCount>";

NSRegularExpression *regex = [NSRegularExpression
                                      regularExpressionWithPattern:pattern
                                      options:NSRegularExpressionCaseInsensitive
                                      error:nil];
NSTextCheckingResult *textCheckingResult = [regex firstMatchInString:xml options:0 range:NSMakeRange(0, xml.length)];

NSRange matchRange = [textCheckingResult rangeAtIndex:1];
NSString *match = [xml substringWithRange:matchRange];
NSLog(@"Found string '%@'", match);

Выход NSLog:

Found string '6'
person zaph    schedule 05.10.2011
comment
Если я хочу получить значение myName между тегом ‹screenName›, мне нужно создать новое регулярное выражение или я могу сделать это в том же самом. - person Prazi; 05.10.2011
comment
Для этого потребуется новое регулярное выражение, поскольку \d+ указывает одну или несколько цифр. Для имени вам понадобится что-то вроде \S+ (если в имени нет пробелов). Существует более общее регулярное выражение, которое должно работать в любом случае: @‹badgeCount›([^‹]+)‹/badgeCount›, которое говорит все до символа ‹. - person zaph; 05.10.2011
comment
Спасибо за вашу помощь. Очень признателен. .... Это означает, что мне нужны два отдельных шаблона 1.‹badgeCount›([^‹]+)‹/badgeCount› для получения badgeCount 2.‹screenName›([^‹]+)‹/screenName› для получения screenName . - person Prazi; 05.10.2011
comment
Да, потому что окружающий текст отличается. - person zaph; 05.10.2011

Чтобы сделать это в Swift 3.0

func getMatchingValueFrom(strXML:String, tag:String) -> String {
    let pattern : String = "<"+tag+">(.*?)</"+tag+">" // original didn't work: "<"+tag+">(\\d+)</"+tag+">"
    let regexOptions = NSRegularExpression.Options.caseInsensitive
    
    do {
        let regex = try NSRegularExpression(pattern: pattern, options: regexOptions)
        let textCheckingResult : NSTextCheckingResult = regex.firstMatch(in: strXML, options: NSRegularExpression.MatchingOptions(rawValue: UInt(0)), range: NSMakeRange(0, strXML.count))!
        let matchRange : NSRange = textCheckingResult.range(at: 1)
        let match : String = (strXML as NSString).substring(with: matchRange)
        return match
    } catch {
        print(pattern + "<-- not found in string -->" + strXML )
        return ""
    }
}

PS: это соответствующее быстрое решение решения @zaph в obj-c

person jeet.chanchawat    schedule 20.09.2016
comment
"<"+tag+">(\\d+)</"+tag+">" у меня не сработало, пришлось использовать "<"+tag+">(.*?)</"+tag+">". - person Alejandro Cotilla; 21.10.2018