Regex для извлечения любого комментария C ++ (как однострочного, так и многострочного, даже если последний находится в середине строки) - PullRequest
0 голосов
/ 13 апреля 2020

Это в основном упражнение, основанное на проблеме, обнаруженной в HackerRank .

Target

Write one regex (для использования в команда подстановки) для извлечения всех комментариев (как // comments, так и /* comments */) из исходного файла C ++ с сохранением не более одной новой строки между последовательными комментариями.

(Для решения для работы с HR, регулярное выражение не нужно так дорабатывать, но я думал, что это не так весело.)

Моя попытка

Приведено следующее регулярное выражение ( см. на Regex101 ), которому соответствует подстановка \1:

.*?(//[^\n]*\n|/\*.*?\*/)/gs

Мне кажется, это хорошая отправная точка, поскольку она правильно фиксирует все комментарии.

fl aws регулярного выражения и моих мыслей о нем

Однако, оно имеет по крайней мере 2 fl aws, как показано ниже.

  1. Это не соответствует тому, что следует за последним комментарием (так этот не-комментарий переживает замену); правки, которые я рассмотрел, но затем отклонил:
    • добавление .*? бесполезно, так как ничего не будет соответствовать
    • добавление .* просто убивает все, кроме первого захваченного совпадения
    • добавление ? показалось многообещающим, поскольку это делает группу захвата жадно необязательной, что позволяет ведущему .*? съесть заключительный не комментарий; однако при этом продвигается с 1-символьным соответствием снова и снова до конца файла, что усложняет имхо следующий пункт 2.
  2. Учитывая два последовательных многострочные комментарии, он соединяет последнюю / единственную строку первой с первой / единственной строкой второй, что мне не нравится. (Этого не происходит с // комментариями, потому что я включаю \n как часть соответствия для комментариев такого типа.)
    • Я думаю, что я должен сохранить не более одного \n от частей Я не собираю, что означает, что я должен изменить ведущий .*? на более сложное регулярное выражение, которое захватывает \n?, чтобы я мог использовать его в замене (вместе с тем, что я уже захватывал).
    • По отношению к пункту 1. добавление ? к исходной группе захвата позволяет двигателю продвигаться с совпадениями в 1 символ, когда он не анализирует комментарий, поэтому это убивает возможность захвата одного \n (все будет захвачено).

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

Пример кода

Бессмысленный код, который я использую для проверки моего регулярного выражения, следующий:

    // my  program in C++

#include <iostream>
int x = 3; /** playing around in
--- // single
a new programming language **/ int y = 4;
using namespace std;

int main ()
{
  cout << /* inline */ "Hello World";i // hello
  cout << "I'm a C++ program"; //use cout // come on /* aaa */ jjj
  return 0;
/* one
two 
three */ int x = 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...