解析Objective-C printf格式字符串?

时间:2013-01-07 18:13:49

标签: objective-c c printf

我希望获得使用NSString构建的+[NSString stringWithFormat:]内的成员范围。解析objective-c格式字符串的最佳方法是什么?由于%@,我不能只使用C格式的字符串解析器。我还需要确保它支持格式排序:%1$d%2$@等。

例如,对于使用[NSString stringWithFormat:@"foo %2$@ bar %1$@", @"Heath", @"Borders"]构建的字符串,我理想地喜欢以下NSArray@[NSMakeRange(15, 5), NSMakeRange(4, 6)]。第一个数组对象对应于格式字符串中的第一个数据元素,第二个数组元素对应于第二个数据元素等。

在这种情况下,API看起来像+ (NSString *) stringWithFormatRanges:(NSArray **)outFormatRanges withFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(1,2);它将返回NSString,就像+[NSString stringWithFormat:]一样,但它也会返回NSArray NSRange每个格式数据元素。

- 编辑 -

鉴于这个问题已经有3年了,我现在对C-only实施感到满意。

2 个答案:

答案 0 :(得分:5)

几年前我对此进行了调查。如果我理解你的问题,就没有简单的方法可以从C或Cocoa格式字符串的格式字符串中获取AST。

我编写了NSXMLElement + elementWithXMLFormat,它允许将NSXMLElements非转义插入到具有特殊%%%@格式代码的格式字符串中,这需要扩展Cocoa的格式。我的技术可能对您有所帮助:

https://github.com/rentzsch/nsxmlelement-elementwithxmlformat/blob/937b54b2a830a8fbbd72d6bc5e48bafd495ddcbd/NSXMLElement%2BelementWithXMLFormat.m#L41

我提取和NUL分隔格式代码,传统运行然后重新组装。

答案 1 :(得分:4)

我为Swift中的那些人编写了一个解析器(以便我可以在Localizable.strings中检测这些占位符并提取在使用这些字符串调用stringWithFormat:时应该给出哪些类型)for my tool {{ 3}}

您可以看到代码的一部分正在进行解析SwiftGen

  • 当然,这是在Swift而不是Objective-C,但我想只要你保留算法的逻辑,我就可以很容易地将其翻译成ObjC。
  • 我的代码不会返回范围作为这些函数的输出 - 只有类型 - 但typesFromFormatString函数中的代码肯定可以访问这些占位符的范围,除了可以完全返回它们检测到的类型(这是一个很容易的变化,我只是不需要那些范围所以我没有将它们包含在返回类型中)

(如果您拥有%d%2$@等占位符的范围,则可以很容易地推断出字符串参数的范围:第一个范围将具有相同的范围{ {1}}作为第一个占位符但是替换值的长度,第二个范围将具有第二个占位符的.location +(firstValue.length-firstRange.length)以考虑偏移量等)

HTH。