stringWithFormat 中的多个参数:“n$”位置说明符
Multiple arguments in stringWithFormat: “n$” positional specifiers
在我们当前的实现中,我们想要更改我们的字符串参数(推送通知 loc-args)并添加新参数。但是我们希望旧版本的用户仍然使用参数 #3,对于新用户,我们希望使用参数 #4。所以在我们的新实现中,我们有以下代码:
NSString *format = @"%2$@, %1$@ ,%4$@";
NSArray *arg = @[@"Argument 1", @"Argument 2",@"Argument 3",@"Argument 4"];
NSString *ouptput = [NSString stringWithFormat:format, arg[0], arg[1], arg[2], arg[3]];
OutPut: Argument 2, Argument 1 ,Argument 3
我们期待它
Argument 2, Argument 1 ,Argument 4
怎样才能做到Argument 4
到位。 stringWithFormat:
的任何其他选择
注意:Apple 锁屏推送通知是正确的 (Argument 2, Argument 1 ,Argument 4
) 但 stringWithFormat:
不是这样处理的
我实现了一个自定义方法来实现预期的输出。此方法可以处理缺少的位置说明符。此方法仅适用于包含位置说明符 %n$@
.
的格式
/**
@param format String format with positional specifier
@param arg Array of arguments to replace positional specifier in format
@return Formatted output string
*/
+(NSString*)stringWithPositionalSpecifierFormat:(NSString*)format arguments:(NSArray*)arg
{
static NSString *pattern = @"%\d\$@";
NSError *error;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:&error];
NSMutableString *mString = [[NSMutableString alloc] initWithString:format];
NSArray *allMatches = [regex matchesInString:format options:0 range:NSMakeRange(0, [format length])];
if (!error && allMatches>0)
{
for (NSTextCheckingResult *aMatch in allMatches)
{
NSRange matchRange = [aMatch range];
NSString *argPlaceholder = [format substringWithRange:matchRange];
NSMutableString *position = [argPlaceholder mutableCopy];
[position replaceOccurrencesOfString:@"%" withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange(0, [position length])];
[position replaceOccurrencesOfString:@"$@" withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange(0, [position length])];
int index = position.intValue;
//Replace with argument
[mString replaceOccurrencesOfString:argPlaceholder withString:arg[index-1] options:NSCaseInsensitiveSearch range:NSMakeRange(0, [mString length])];
}
}
return mString;
}
在我们当前的实现中,我们想要更改我们的字符串参数(推送通知 loc-args)并添加新参数。但是我们希望旧版本的用户仍然使用参数 #3,对于新用户,我们希望使用参数 #4。所以在我们的新实现中,我们有以下代码:
NSString *format = @"%2$@, %1$@ ,%4$@";
NSArray *arg = @[@"Argument 1", @"Argument 2",@"Argument 3",@"Argument 4"];
NSString *ouptput = [NSString stringWithFormat:format, arg[0], arg[1], arg[2], arg[3]];
OutPut: Argument 2, Argument 1 ,Argument 3
我们期待它
Argument 2, Argument 1 ,Argument 4
怎样才能做到Argument 4
到位。 stringWithFormat:
注意:Apple 锁屏推送通知是正确的 (Argument 2, Argument 1 ,Argument 4
) 但 stringWithFormat:
不是这样处理的
我实现了一个自定义方法来实现预期的输出。此方法可以处理缺少的位置说明符。此方法仅适用于包含位置说明符 %n$@
.
/**
@param format String format with positional specifier
@param arg Array of arguments to replace positional specifier in format
@return Formatted output string
*/
+(NSString*)stringWithPositionalSpecifierFormat:(NSString*)format arguments:(NSArray*)arg
{
static NSString *pattern = @"%\d\$@";
NSError *error;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:&error];
NSMutableString *mString = [[NSMutableString alloc] initWithString:format];
NSArray *allMatches = [regex matchesInString:format options:0 range:NSMakeRange(0, [format length])];
if (!error && allMatches>0)
{
for (NSTextCheckingResult *aMatch in allMatches)
{
NSRange matchRange = [aMatch range];
NSString *argPlaceholder = [format substringWithRange:matchRange];
NSMutableString *position = [argPlaceholder mutableCopy];
[position replaceOccurrencesOfString:@"%" withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange(0, [position length])];
[position replaceOccurrencesOfString:@"$@" withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange(0, [position length])];
int index = position.intValue;
//Replace with argument
[mString replaceOccurrencesOfString:argPlaceholder withString:arg[index-1] options:NSCaseInsensitiveSearch range:NSMakeRange(0, [mString length])];
}
}
return mString;
}