Я должен извлечь однострочные комментарии из qmake
файл проекта.
Правила просты: комментарий начинается с #
символ и начинаются с переноса строки \n
,
Итак, я прочитал некоторую документацию о QRegExp
и напишите такой код, чтобы напечатать все комментарии в файле qmake:
QRegExp re ("#(.*)\n$");
re.setMinimal (true);
int comment_index = 0;
while ((comment_index = _project_contents.indexOf (comment_expr, comment_index)) != -1)
{
QString comment_text = comment_expr.cap (0);
qDebug() << "Comment 1" << comment_text;
}
Но это не работает правильно — просто все содержимое файла проекта было напечатано.
Где моя ошибка? как я понимаю из документов, это должно работать, но это не так.
Постскриптум Я новичок в регулярных выражениях, поэтому, пожалуйста, не бейте меня 🙂
Проблема в том, что .
msgstr «соответствует любому символу (включая перевод строки).». И $
это конец строки.
Вы можете попробовать использовать not-newline — [^\n]
и изменение $
в (\n|$)
(перевод строки или конец строки):
"#[^\n]*(\n|$)"
Но тогда это соответствует #
в любом месте, а не только в начале строки, поэтому давайте попробуем это:
"(^|\n)#[^\n]*(\n|$)"
^
это начало строки, поэтому в основном (^|\n)
(начало строки или новая строка) перед началом строки.
Вы видите проблему там? Что делать, если у вас есть 2 комментария в 2 последовательных строках? Вы будете сопоставлять только первое, так как новая строка будет использоваться во время сопоставления с первым (поскольку следующий матч начинается там, где закончился предыдущий).
Обходным путем для этого является использование упреждающего просмотра:
"(^|\n)#[^\n]*(?=\n|$)"
Это приводит к тому, что конечный символ новой строки не включается в совпадение (но он все еще проверяется), поэтому позиция будет находиться непосредственно перед новой строкой, и следующий матч может использовать ее.
Может ли #
предшествовать пробелы? Если это так, проверьте наличие нуля или более пробелов (\s*
):
"(^|\n)\s*#[^\n]*(?=\n|$)"
Других решений пока нет …