テンプレートの代わりにブロックを取るNSRegularExpressionの– stringByReplacingMatchesInString:options:range:withTemplate:
メソッドのバリエーションが必要でした。ブロックの戻り値は置換値として使用されます。あなたが想像できるように、これはテンプレートより柔軟です。 Perlの正規表現で/e
修飾子を使用するような並べ替えをします。これは正常なObjective-Cブロックの実装ですか?
そこで、メソッドを追加するカテゴリを作成しました。これは、それは少し奇妙な感じの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
:これは私が思いついたものです。しかし、私はそれについてのいくつかの質問があります:
- これは、このような方法を実装するための純粋な方法のようですか?
-enumerateMatchesInString:options:range:usingBlock:
を使って内部構造を実装する方法はありますか?私はそれを試しましたが、ブロック内からpos
に割り当てることができませんでした。しかし、それを動作させる方法があれば、NSMatchingFlagsとBOOLを渡して、そのメソッドと同じ方法でそれらを処理することは賢明でしょう。できますか?
更新
デイブ・デロングからの回答のおかげで、私はブロックを使用して新しいバージョンを持っている:
@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
素晴らしい作品
、ありがとう!
これは本当に便利です。ありがとうございました! –