10

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);它会返回一个NSStringjust like +[NSString stringWithFormat:],但它也会返回每个格式数据元素的一个NSArraywith NSRanges。

- 编辑 -

鉴于这个问题已经存在 3 年了,此时我对仅 C 的实现感到满意。

4

2 回答 2

5

几年前我研究过这个。如果我理解您的问题,则没有简单的方法可以从 C 或 Cocoa 格式字符串的格式字符串中获取 AST。

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

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

我只提取格式代码并对其进行 NUL 分隔,以传统方式运行它,然后重新组装。

于 2013-01-07T18:35:25.930 回答
4

我为我的工具SwiftGen用 Swift 编写了一个解析器(这样我就可以检测其中的占位符Localizable.strings并提取在使用这些字符串调用时应该给出哪些类型)stringWithFormat:

您可以在我的 GitHub 上看到执行解析的部分代码。

  • 当然,它是 Swift 而不是 Objective-C,但我想它很容易转换为 ObjC,只要你保持算法的逻辑。
  • 我的代码也没有返回这些函数的输出范围——只有类型——但是typesFromFormatString函数中的代码肯定可以访问这些占位符的范围,并且除了检测到的类型之外,还可以完全返回它们(这是一个简单的改变,我只是不需要这些范围,所以我没有将它们包含在返回类型中)

%d(一旦有了or等​​占位符的范围%2$@,就很容易推断出字符串参数的范围:第一个范围将与.location第一个占位符相同,但替换值的长度,第二个范围将有第二.location个占位符的 + (firstValue.length-firstRange.length) 将偏移量考虑在内,等等)

HTH。

于 2016-07-21T20:03:29.357 回答