我想要一個NSRegularExpression的– stringByReplacingMatchesInString:options:range:withTemplate:
方法的變體,它採用一個塊而不是模板。塊的返回值將被用作重置值。如你所想,這比模板更靈活。有點像在Perl正則表達式中使用/e
修飾符。這是一個理智的Objective-C塊實現嗎?
所以我寫了一個類添加方法。這是我想出了:
@implementation NSRegularExpression (Block)
- (NSString *)stringByReplacingMatchesInString:(NSString *)string
options:(NSMatchingOptions)options
range:(NSRange)range
usingBlock:(NSString* (^)(NSTextCheckingResult *result))block
{
NSMutableString *ret = [NSMutableString string];
NSUInteger pos = 0;
for (NSTextCheckingResult *res in [self matchesInString:string options:options range:range]) {
if (res.range.location > pos) {
[ret appendString:[string substringWithRange:NSMakeRange(pos, res.range.location - pos)]];
}
pos = res.range.location + res.range.length;
[ret appendString:block(res)];
}
if (string.length > pos) {
[ret appendString:[string substringFromIndex:pos]];
}
return ret;
}
@end
這是我第一次在目的C.玩積木的嘗試,感覺有點怪異,但它似乎運作良好。我有幾個關於它的問題,但:
- 這似乎是一個理智的方式來實現這樣的方法嗎?
- 有沒有一些方法可以使用
-enumerateMatchesInString:options:range:usingBlock:
來實現它的內部?我試過了,但是不能從塊內分配到pos
。但是如果有辦法讓它工作,那麼也可以通過NSMatchingFlags和BOOL來處理它們,就像那個方法一樣。 DO-能?
更新
感謝來自Dave德隆的回答,我已經使用了塊新版本:
@implementation NSRegularExpression (Block)
- (NSString *)stringByReplacingMatchesInString:(NSString *)string
options:(NSMatchingOptions)options
range:(NSRange)range
usingBlock:(NSString * (^)(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop))block
{
NSMutableString *ret = [NSMutableString string];
__block NSUInteger pos = 0;
[self enumerateMatchesInString:string options:options range:range usingBlock:^(NSTextCheckingResult *match, NSMatchingFlags flags, BOOL *stop)
{
if (match.range.location > pos) {
[ret appendString:[string substringWithRange:NSMakeRange(pos, match.range.location - pos)]];
}
pos = match.range.location + match.range.length;
[ret appendString:block(match, flags, stop)];
}];
if (string.length > pos) {
[ret appendString:[string substringFromIndex:pos]];
}
return [NSString stringWithString:ret];
}
@end
偉大的作品,謝謝!
這真的很方便。謝謝! – 2012-08-09 10:07:28