Stack Exchange
NSRegularExpression to extract text between two XML tags
How to extract the value "6" between the "badgeCount" tags using NSRegularExpression. Following is the response from the server:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><badgeCount>6</badgeCount><rank>2</rank><screenName>myName</screenName>

Following is the code I tried but not getting success. Actually it goes in else part and prints "Value of regex is nil":
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");

If you could provide sample code that would be much appreciated.
NOTE: I don't want to use NSXMLParser.

Why don't you want to use an xml parser to parse xml?

And what have you tried so far?

No need of NSXMLParser for extracting just a couple of values ... I did got the needed Regular Expression "(?<=badgeCount>)(?:[^])*?(?=</badgeCount)" using the http://gskinner.com/RegExr/ online tool but unable to use the same expression in NSRegular Expression...

Edit your question to include the code you tried, and explain exactly what is not working about it.

Example:
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 output:
Found string '6'


If I want to get the value "myName" between tag  do I need  to create new regular expression or could I do it in the same.

It would require a new regex because "\d+" specifies one or more digits.  For a name you will need something like "\S+" (if there are no spaces in the name).  There is a more general regex that should work in either case: @"([^<]+)", that says anything up to the "<" character.

Thanks for all your help. Much appreciated. .... So that means I need two separate patterns 1.([^<]+) for getting badgeCount 2.([^<]+) for getting screenName.

Yes because the surrounding text is different.

To do it in 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 ""
    }
}

P.S : This is corresponding swift solution of @zaph's solution in obj-c

"<"+tag+">(\\d+)</"+tag+">" did not work for me, I had to use "<"+tag+">(.*?)</"+tag+">".
