10

NSStringビルドされた with内のメンバーの範囲を取得したい+[NSString stringWithFormat:]。Objective-C フォーマット文字列を解析する最良の方法は何ですか? のため、C 形式の文字列パーサーだけを使用することはできません%@。また、フォーマット順序をサポートしていることも確認する必要があります: %1$d%2$@など。

たとえば、 で構築された文字列では[NSString stringWithFormat:@"foo %2$@ bar %1$@", @"Heath", @"Borders"]、理想的には次のようになりNSArrayます@[NSMakeRange(15, 5), NSMakeRange(4, 6)]。最初の配列オブジェクトはフォーマット文字列の最初のデータ要素に対応し、2 番目の配列オブジェクトは 2 番目のデータ要素などに対応します。

この場合、API は次のようになります。 と同じように+ (NSString *) stringWithFormatRanges:(NSArray **)outFormatRanges withFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(1,2);を返しますが、各フォーマット データ要素のwithも返します。NSString+[NSString stringWithFormat:]NSArrayNSRange

- 編集 -

この質問は 3 年前のものなので、現時点では C のみの実装に満足しています。

4

2 に答える 2

5

私は数年前にこれを調べました。あなたの質問が理解できたとしても、C または Cocoa フォーマット文字列のフォーマット文字列から AST を取得する簡単な方法はありません。

%%%@私は NSXMLElement+elementWithXMLFormat を書きました。これは、Cocoa のフォーマットを拡張する必要がある特殊なフォーマット コードを使用して、フォーマット文字列に NSXMLElements をエスケープせずに挿入できるようにします。私のテクニックはあなたに役立つかもしれません:

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 で解析を行っているコードの一部を見ることができます。

  • 確かに、Objective-C ではなく Swift ですが、アルゴリズムのロジックを保持している限り、ObjC に簡単に変換できると思います。
  • 私のコードは、これらの関数の出力として範囲を返さず、型のみを返しますが、typesFromFormatString関数内のコードは確実にこれらのプレースホルダーの範囲にアクセスでき、検出された型に加えてそれらを完全に返すことができます (これは簡単な変更です)。 、これらの範囲は必要なかったので、戻り値の型に含めませんでした)

(%dまたはのようなプレースホルダーの範囲を取得したら%2$@、文字列パラメーターの範囲を推測するのは簡単です。最初の範囲は最初の.locationプレースホルダーと同じになりますが、置換された値の長さは、2 番目の範囲になります。 2 番目の.locationプレースホルダー + (firstValue.length-firstRange.length) の オフセットを考慮に入れるなど)

HTH。

于 2016-07-21T20:03:29.357 に答える