Разбор Objective-C printf Форматирование строк?
Я хочу получить диапазоны членов внутри NSString
, построенных с помощью +[NSString stringWithFormat:]
. Каков наилучший способ разбора строки формата objective-c? Я не могу просто использовать синтаксический синтаксический анализатор формата C из-за %@
. Я также должен убедиться, что он поддерживает порядок форматирования: %1$d
, %[email protected]
и т.д.
Например, с строкой, построенной с помощью [NSString stringWithFormat:@"foo %[email protected] bar %[email protected]", @"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
каждого элемента данных формата.
- EDIT -
Учитывая, что этот вопрос составляет 3 года, я был бы доволен реализацией C-only на этом этапе.
Ответы
Ответ 1
Я изучил это несколько лет назад. Если я понимаю ваш вопрос, нет простого способа получить AST из строки формата для строк формата C или Cocoa.
Я написал NSXMLElement + elementWiспасибоMLFormat, который допускал несвязанную вставку NSXMLElements в строку формата со специальным кодом формата %%%@
, который требовал расширения формата Cocoa. Мой метод может быть вам полезен:
https://github.com/rentzsch/nsxmlelement-elementwithxmlformat/blob/937b54b2a830a8fbbd72d6bc5e48bafd495ddcbd/NSXMLElement%2BelementWithXMLFormat.m#L41
Я извлекаю и NUL-разграничивает только коды формата, запускаю его традиционно, а затем снова собираю.
Ответ 2
Я написал синтаксический анализатор для тех, кто работает в Swift (чтобы я мог обнаружить эти заполнители в Localizable.strings
и извлечь, какие типы должны были быть получены при вызове stringWithFormat:
с этими строками) для моего инструмента SwiftGen
Вы можете увидеть часть кода, выполняющую синтаксический анализ, на моем GitHub.
- Конечно, это в Swift, а не в Objective-C, но я думаю, что это легко переносится в ObjC, если вы сохраняете логику алгоритма.
- Мой код не возвращает диапазоны в качестве вывода этих функций - только типы - но код в функциях
typesFromFormatString
определенно имеет доступ к диапазонам этих заполнителей и может полностью возвращать их в дополнение к обнаруженному типу (что легко изменить, мне просто не нужны эти диапазоны, поэтому я не включил их в тип возвращаемого значения)
(Если у вас есть диапазоны для заполнителей, таких как %d
или %[email protected]
, будет легко определить диапазоны для строковых параметров: первый диапазон будет иметь такое же .location
Как и первый заполнитель, но длина замененное значение, у 2-го диапазона будет .location
2-го заполнителя + (firstValue.length-firstRange.length) для учета смещения и т.д.)
НТН.