【问题标题】:NSRegularExpression to extract text between two XML tagsNSRegularExpression 提取两个 XML 标记之间的文本
【发布时间】:2021-05-13 04:44:58
【问题描述】:

如何使用 NSRegularExpression 提取“badgeCount”标签之间的值“6”。以下是来自服务器的响应:

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

以下是我尝试但未成功的代码。实际上它进入 else 部分并打印“正则表达式的值为零”:

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。

【问题讨论】:

  • 为什么不想使用xml解析器来解析xml?
  • 到目前为止你尝试过什么?
  • 不需要 NSXMLParser 来提取几个值...我确实得到了所需的正则表达式 "(?)(?:[^])*?(?=gskinner.com/RegExr 在线工具但无法在 NSRegular Expression 中使用相同的表达式...
  • 编辑您的问题以包含您尝试过的代码,并准确解释它的问题所在。

标签: objective-c regex swift swift3 nsregularexpression


【解决方案1】:

例子:

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'

【讨论】:

  • 如果我想在标签 之间获取值“myName”,我需要创建新的正则表达式还是可以这样做。
  • 它需要一个新的正则表达式,因为 "\d+" 指定一个或多个数字。对于名称,您将需要类似“\S+”的名称(如果名称中没有空格)。有一个更通用的正则表达式在任何一种情况下都应该起作用:@“([^”,它表示“
  • 感谢您的所有帮助。非常感激。 .... 所以这意味着我需要两个单独的模式 1.([^ 用于获取 badgeCount 2.([^ 用于获取 screenName .
  • 是的,因为周围的文字不同。
【解决方案2】:

在 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 : 这是@zaph在obj-c中的解决方案对应的swift解决方案

【讨论】:

  • "&lt;"+tag+"&gt;(\\d+)&lt;/"+tag+"&gt;" 对我不起作用,我不得不使用 "&lt;"+tag+"&gt;(.*?)&lt;/"+tag+"&gt;"
猜你喜欢
  • 1970-01-01
  • 2014-11-13
  • 2020-06-29
  • 1970-01-01
  • 1970-01-01
  • 2011-12-31
  • 1970-01-01
  • 2016-10-23
  • 1970-01-01
相关资源
最近更新 更多