我有一组返回的XML示例:
<rsp stat="ok">
<site>
<id>1234</id>
<name>testAddress</name>
<hostname>anotherName</hostname>
...
</site>
<site>
<id>56789</id>
<name>ba</name>
<hostname>alphatest</hostname>
...
</site>
</rsp>
我想提取<name></name>
中的所有内容,但不提取标记本身,并且仅针对第一个实例(或基于其他一些测试选择哪个项目)。
这是否可以使用正则表达式?
答案 0 :(得分:3)
<disclaimer>
我不使用Objective-C </disclaimer>
您应该使用XML parser,not regexes。 XML is not a regular language,hence not easely parseable a regular expression。 Don't do it 强>
Never use regular expressions or basic string parsing to process XML。现在常用的每种语言都有完美的XML支持。 XML是一个看似复杂的标准,你的代码不太可能正确地解析所有格式良好的XML输入,即使它是,你也浪费你的时间,因为(正如刚才提到的)每一种语言都是常见用法有XML支持。使用正则表达式解析XML是不专业的。
您可以使用Expat,Objective C bindings。
答案 1 :(得分:2)
在不知道您的语言或环境的情况下,这里有一些perl表达式。希望它能为您的应用提供正确的想法。
用于捕获标记文本内容的正则表达式如下所示:
m/>([^<]*)</
这将捕获每个标记中的内容。您必须循环匹配才能提取所有内容。请注意,这不会考虑自终止标记。你需要一个带有负面lookbehinds的正则表达式引擎才能实现这一目标。在不了解您的环境的情况下,很难说它是否会得到支持。
您也可以使用以下内容删除源中的所有代码:
s/<[^>]*>//g
另外,根据您的环境,如果您可以使用XML解析库,它将使您的生活更轻松。毕竟,通过采用正则表达式方法,您将失去XML真正为您提供的所有内容(结构化数据,上下文感知等)。
答案 2 :(得分:1)
正如其他人所说,你应该真的使用NSXMLParser
来做这类事情。
但是,如果您只需要提取名称标签中的内容,那么RegexKitLite可以很容易地完成:
NSString * xmlString = ...;
NSArray * captures = [xmlString arrayOfCaptureComponentsMatchedByRegex:@"<name>(.*?)</name>"];
for (NSArray * captureGroup in captures) {
NSLog(@"Name: %@", [captureGroup objectAtIndex:1];
}
答案 3 :(得分:1)
此类任务的最佳工具是XPath。
NSURL *rspURL = [NSURL fileURLWithPath:[@"~/rsp.xml" stringByExpandingTildeInPath]];
NSXMLDocument *document = [[[NSXMLDocument alloc] initWithContentsOfURL:rspURL options:NSXMLNodeOptionsNone error:NULL] autorelease];
NSArray *nodes = [document nodesForXPath:@"/rsp/site[1]/name" error:NULL];
NSString *name = [nodes count] > 0 ? [[nodes objectAtIndex:0] stringValue] : nil;
如果您想要网站名称为id 56789,请使用此XPath:/rsp/site[id='56789']/name
。我建议您阅读W3Schools XPath tutorial以快速了解XPath语法。
答案 4 :(得分:0)
小心命名空间:
<prefix:name xmlns:prefix="">testAddress</prefix:name>
是等效的XML,它将破坏基于regexp的代码。对于XML,请使用XML解析器。对于像这样的事情,XPath是你的朋友。下面的XPath代码将返回一系列带有您想要的信息的字符串:
./rsp/site/name/text()
Cocoa有NSXML support for XPath。