– stringByReplacingMatchesInString:options:range:withTemplate:
テンプレートの代わりにブロックを取るNSRegularExpression のメソッドのバリエーションが必要でした。ブロックの戻り値が置換値として使用されます。ご想像のとおり、これはテンプレートよりも柔軟です。/e
Perl 正規表現で修飾子を使用するようなものです。
そこで、メソッドを追加するカテゴリを作成しました。これは私が思いついたものです:
@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
Objective C でブロックを操作するのはこれが初めての試みです。少し奇妙に感じますが、うまく機能しているようです。ただし、それについていくつか質問があります。
- これは、そのようなメソッドを実装するための正気な方法のように思えますか?
- を使用して内部を実装する方法はあり
-enumerateMatchesInString:options:range:usingBlock:
ますか?pos
やってみたのですが、ブロック内から代入できませんでした。しかし、それを機能させる方法があれば、NSMatchingFlags と BOOL も渡して、その方法と同じ方法で処理するのがクールでしょう。できる?
アップデート
Dave DeLong からの回答のおかげで、ブロックを使用した新しいバージョンを入手できました。
@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
うまくいきました、ありがとう!