Интерполяция строк в стиле Ruby с помощью iOS NSRegularExpression

Я пытаюсь создать HTML-вывод для модели в своем приложении. Это будет эффективно проходить и заполнять различные места внутри HTML-файла соответствующими значениями в модели. Изначально я собирался просто взять HTML-шаблон в виде отформатированной строки, но если что-то изменится позже в макете или что-то еще, это станет очень грязным и утомительным, чтобы сопоставить порядок значений с порядком, в котором они появляются в шаблоне. .

Вместо этого я пытаюсь выполнить интерполяцию файла в стиле Ruby. Везде, где мне нужно значение из модели, я помещаю имя атрибута модели, который мне нужен, например: #{key.path}.

Затем я пытаюсь обработать это с помощью следующего регулярного выражения: @"#{([^}]+)}".

Чтобы обработать это, я использую следующую настройку:

NSString *processedTemplate = [regex stringByReplacingMatchesInString:template 
                                options:0 
                                range:NSMakeRange(0, template.length) 
                                withTemplate:[self valueForKeyPath:@"$1"]];

Однако, когда я запускаю это, я получаю сообщение об ошибке:

*** Terminating app due to uncaught exception 'NSUnknownKeyException', 
    reason: '[<Plan 0x78349d0> valueForUndefinedKey:]: this class is not 
             key value coding-compliant for the key $1.'

Я ожидаю, что смогу использовать совпадение регулярных выражений и использовать его для получения значения, совместимого с кодированием ключ-значение, в моей модели. Однако это явно не работает так, как я его использую.

Кстати, я думаю, что использую это право, но когда я просто запускаю это, чтобы заменить withTemplate:@"$1", я получаю NULL. Итак, я попробовал это, используя:

    NSString *processedTemplate = [template stringByReplacingOccurrencesOfString:@"#{([^}]+)}" 
                                    withString:@"$1"
                                       options:NSRegularExpressionSearch 
                                         range:NSMakeRange(0, template.length)];

Однако, когда я запускаю это, он не заменяет раздел в (). Так или иначе, я что-то не так делаю. У кого-нибудь есть указатели/решения?

Обновить

Таким образом, похоже, что параметр withString: будет интерпретировать @"$1" как все, что было найдено данными совпадения регулярного выражения. Есть ли другой способ получить данные о совпадении, чтобы их можно было передать в такие методы, как valueForKeyPath:?

Обновить

С моей стороны, я не знаю, почему, но мое регулярное выражение #{([^}]+)} не соответствует тому, что я ожидал. Любой другой симулятор регулярных выражений, с которым я столкнулся, кажется, отлично подходит, но он не соответствует obj-c на iOS. Есть ли что-то, что мне не хватает с escape-символами в наборе символов #{}?


person Josh Kovach    schedule 15.12.2011    source источник
comment
Я нашел решение общей проблемы здесь stackoverflow.com/questions/8935466/, но я держу это открытым на случай, если кто-нибудь сможет понять, почему моя реализация выше на самом деле не работала, или как исправить.   -  person Josh Kovach    schedule 21.01.2012


Ответы (1)


Что за объект self в вашем первом примере? Вы переопределили valueForKeyPath:?

Метод -valueForKeyPath: определен для NSObject для возврата значения на основе путей ключей KVC. Код

obj = [anotherObj valueForKeyPath: @"foo.bar.baz"];

сначала отправит foo в anotherObj, затем отправит bar в результат, затем отправит baz в результат этого и вернет окончательный результат.

По сути, среда выполнения жалуется, что у вас нет метода с именем -$1.

И, кстати, в Objective-C параметры методов оцениваются до самого метода, поэтому

[self valueForKeyPath:@"$1"]

оценивается перед stringByReplacingMatchesInString:, а $1 не означает ничего особенного для valueForKeyPath:.

person JeremyP    schedule 15.12.2011
comment
Это расширение NSObject. Я могу использовать setValue:forKeyPath:] и valueForKey: таким образом, поэтому я не понимаю, почему я не могу также использовать valueForKeyPath:. Разве @$1 не следует просто интерпретировать как возвращаемое значение из совпадения с регулярным выражением? - person Josh Kovach; 15.12.2011
comment
@Josh: № @"$1" — это буквальная строка, состоящая из знака доллара, за которым следует цифра, обозначающая единицу. - person JeremyP; 15.12.2011