在iPhone上使用NSRegularExpression和捕获组

5

我需要一点有关 iPhone 正则表达式的启动知识。基本上,我在一个私人 MediaWiki 中有一个日期列表,格式为
*185 BC:这里是一些事件
*2001:远晚于此的其他事件

现在,我想将其解析成一个具有 NSDate 属性和 - 比如说 - NSString 属性的对象。到目前为止,我有了以下代码:(rawContentString 包含页面的 mediawiki 语法)

NSString* regexString =@"\\*( *[0-9]{1,}.*): (.*)";
NSRegularExpressionOptions options = NSRegularExpressionCaseInsensitive;
NSError* error = NULL;

NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:regexString options:options error:&error];
if (error) {
    NSLog(@"%@", [error description]);
}

NSArray* results = [regex matchesInString:rawContentString options:0 range:NSMakeRange(0, [rawContentString length])];
for (NSTextCheckingResult* result in results) {

    NSString* resultString = [rawContentString substringWithRange:result.range];
    NSLog(@"%@",resultString);
}

很不幸,我认为正则表达式没有按照我的期望工作,并且我不知道如何捕获匹配的日期和文本。希望能得到任何帮助。

顺便说一下:是否有关于MediaWiki语法的正则表达式模式编译?

提前致谢 Heiko *


如果我是你,我会使用http://regexkit.sourceforge.net/。根据我的经验,它的性能要好得多,通常你可以得到你所需要的东西。 - Blitz
嗨,谢谢你的提示。我已经研究过了。但是我的应用程序只会在4.0及以上版本上运行,所以我假设使用IOS的正则表达式功能会更好。这样不对吗? - HeikoG
据我所知,它们使用相同的底层东西,而且RegexKit似乎更容易使用 - 但我想这真的是个人喜好。但也许还有其他人对此了解更多。 - Blitz
3
NSRegularExpression 和 RegexKitLite 都使用 libicucore 中的 ICU 正则表达式引擎。理论上它们应该提供相同的结果,但实际上可能存在一些极小的差异(例如,RegexKitLite 必须完全使用公共 API,而 NSRegularExpression 可以使用私有 API)。我认为这种差异就像 @LordT 所说的 "个人偏好"。此外,在编写本文时,RegexKitLite 几乎可以在所有 Mac OS X 和 iOS 版本上运行。 - johne
2个回答

3
我的问题是我使用的是matchesInString,而我需要使用firstMatchInString,因为它可以在一个NSTextCheckingResult中返回多个范围。
虽然这个方法有些不直观,但它确实有效。
我从http://snipplr.com/view/63340/获得了答案。
我的代码(用于解析信用卡磁道数据):
NSRegularExpression *track1Pattern = [NSRegularExpression regularExpressionWithPattern:@"%.(.+?)\\^(.+?)\\^([0-9]{2})([0-9]{2}).+?\\?." options:NSRegularExpressionCaseInsensitive error:&error];

NSTextCheckingResult *result = [track1Pattern firstMatchInString:trackString options:NSMatchingReportCompletion range:NSMakeRange(0, trackString.length)];

self.cardNumber = [trackString substringWithRange: [result rangeAtIndex:1]];
self.cardHolderName = [trackString substringWithRange: [result rangeAtIndex:2]];
self.expirationMonth = [trackString substringWithRange: [result rangeAtIndex:3]];
self.expirationYear = [trackString substringWithRange: [result rangeAtIndex:4]];

2
关于正则表达式,我认为以下内容比较合适:
\*([ 0-9]{1,}.*):(.*)

应该更好地满足您的需求。您没有转义第一个*,而且为什么第一组语句中有一个*?


嘿,谢谢 - 看起来干净多了 :-) 至于第一组中的 :我想为 '' 和日期之间的空格做准备。 - HeikoG
这是有道理的,但那样应该是 [ ]* 而不是 * - Blitz
太好了 :-) 我在另一个正则表达式中也有同样的东西。所以你刚刚为我解决了几个问题...谢谢 - HeikoG

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接