如何检查NSString格式是否包含与可变参数相同数量的说明符?

Met*_*ngs 3 objective-c variadic-functions nsstring stringwithformat

为了确保NSString initWithFormat:arguments:按预期返回的格式化字符串是正确的,我需要确定是否有与参数相同数量的格式说明符。下面是一个(稍作和高度编辑的)示例:

- (void)thingsForStuff:(CustomStuff)stuff, ...
{
    NSString *format;
    switch (stuff)
    {
        case CustomStuffTwo:
            format = @"Two things: %@ and %@";
        break;

        case CustomStuffThree:
            format = @"Three things: %@, %@, and %@";
        break;

        default:
            format = @"Just one thing: %@";
        break;
    }

    va_list args;
    va_start(args, method);
    // Want to check if format has the same number of %@s as there are args, but not sure how
    NSString *formattedStuff = [[NSString alloc] initWithFormat:format arguments:args];
    va_end(args);

    NSLog(@"Things: %@", formattedStuff);
}
Run Code Online (Sandbox Code Playgroud)

使用这种方法,[self thingsForStuff:CustomStuffTwo, @"Hello", @"World"]会记录

“两件事:你好和世界”

...但是[self thingsForStuff:CustomStuffTwo, @"Hello"]会记录

“两件事:你好和”

...在发生之前,最好将其捕获。

有没有一种方法可以计算字符串中的格式说明符,最好是轻量级的/便宜的?

Ras*_*spu 5

好吧,我创建了自己的正则表达式,我不知道它是否能抓住所有人,并且可能最终会发现一些误报,但似乎对我有用:

static NSString *const kStringFormatSpecifiers =
@"%(?:\\d+\\$)?[+-]?(?:[lh]{0,2})(?:[qLztj])?(?:[ 0]|'.{1})?\\d*(?:\\.\\d+)?[@dDiuUxXoOfeEgGcCsSpaAFn]";
Run Code Online (Sandbox Code Playgroud)

您可以使用以下方法计算参数数量:

NSRegularExpression *regEx = [NSRegularExpression regularExpressionWithPattern: kStringFormatSpecifiers options:0 error:nil];
NSInteger numSpecifiers = [regEx numberOfMatchesInString: yourString options:0 range:NSMakeRange(0, yourString.length)];
Run Code Online (Sandbox Code Playgroud)