Найти несколько комментариев Objective C для файла в определенном формате с помощью Ruby Regex - PullRequest
1 голос
/ 20 января 2012

Я пишу сценарий Ruby, который использует регулярные выражения для поиска всех комментариев определенного формата в файлах исходного кода Objective-C.

Формат

/* <Headline_in_caps> <#>:
    <Comment body>
**/

Я хочу записать заголовок в шапках, номер и текст комментария.

С помощью приведенного ниже регулярного выражения я могу найти один комментарий в этом формате в большей части текста.

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

Тело комментария может содержать все символы, кроме **/ и */, которые оба означают конец комментария. Правильно ли я полагаю, что регулярное выражение найдет несколько совпадений с целым регулярным выражением, обрабатывая текст только один раз?

\/\*\s*([A-Z]+). (\d)\:([\w\d\D\W]+)\*{2}\//x

Разбитое на части регулярное выражение делает это:

\/\* - находит начало комментария

\s* - поиск пробелов

([A-Z]+) - захватывает заглавные буквы

.<space> - найти пробел между заглавными буквами и цифрами

(\d) - захватить цифру

\: - найти двоеточие

([\w\W\d\D]+) - захватывает тело сообщения, которое может содержать все допустимые символы, кроме **/ или */

\*{2}\/ - находит конец комментария

Вот пример, все от первого /* до второго **/ захвачено .:

/*

 HEADLINE 1:

 Comment body.

 **/

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// This text and method declaration are captured
// The regex captures from HEADLINE to the end of the comment "meddled in." inclusively.

/*
       HEADLINE 2:

       Should be captured separately and without Objective-C code meddled in. 
 **/

}

Вот пример на Rubular: http://rubular.com/r/4EoXXotzX0

Я использую gsub для обработки регулярного выражения в строке всего файла, используя Ruby 1.9.3. Другая проблема, с которой я столкнулся, заключается в том, что gsub дает мне то, что игнорирует Rubular, является ли это регрессией или Rubular использует другой метод, который дает то, что я хочу?

В этом вопросе Regex, сопоставляющее множественные вхождения для файла и в строке для множественных вхождений, ответом является использование g для глобальной опции, которая недопустима в Ruby regex.

Ответы [ 2 ]

1 голос
/ 21 января 2012

Измените это: ([\w\W\d\D]+)
На это: ([\w\W\d\D]+?)

Это приведет к тому, что регулярное выражение станет не жадным и остановится, как только увидит следующее закрытие **/.(Обновленный заголовок: http://rubular.com/r/Whm31AJ6Kg)

Также обратите внимание, что [\w\W\d\D] соответствует абсолютно любому символу и может быть проще написано как [\w\W]. В качестве альтернативы вы можете сопоставить тело просто с [^*\/], чтоТакже избегайте вышеуказанной проблемы сопоставления через закрытие. (Обновленный рубуляр: http://rubular.com/r/2h0kGYkdVQ)

0 голосов
/ 20 января 2012

Решение:

  • Разделить всю строку с помощью '*/' (конец комментария)
  • Если разделение возвращает только один элемент, в строке нет комментариев
  • В противном случае для каждого токена, кроме последнего, используйте RegExp %r{/\*(.*)$} (начиная с '/ *' до конца токена) для захвата всего прокомментированного содержимого (вы можете использовать здесь более сложный RegExp для сбора дополнительных данных в комментарии)

Возможно, это не самое прекрасное решение, но оно должно делать свою работу. И это не пуленепробиваемое, если у вас есть в исходном коде Objective-C что-то вроде строки ниже, мое решение потерпит неудачу.

 char *myString = "a comment /*  */";
...