Это в основном упражнение, основанное на проблеме, обнаруженной в HackerRank .
Target
Write one regex (для использования в команда подстановки) для извлечения всех комментариев (как // comments
, так и /* comments */
) из исходного файла C ++ с сохранением не более одной новой строки между последовательными комментариями.
(Для решения для работы с HR, регулярное выражение не нужно так дорабатывать, но я думал, что это не так весело.)
Моя попытка
Приведено следующее регулярное выражение ( см. на Regex101 ), которому соответствует подстановка \1
:
.*?(//[^\n]*\n|/\*.*?\*/)/gs
Мне кажется, это хорошая отправная точка, поскольку она правильно фиксирует все комментарии.
fl aws регулярного выражения и моих мыслей о нем
Однако, оно имеет по крайней мере 2 fl aws, как показано ниже.
- Это не соответствует тому, что следует за последним комментарием (так этот не-комментарий переживает замену); правки, которые я рассмотрел, но затем отклонил:
- добавление
.*?
бесполезно, так как ничего не будет соответствовать - добавление
.*
просто убивает все, кроме первого захваченного совпадения - добавление
?
показалось многообещающим, поскольку это делает группу захвата жадно необязательной, что позволяет ведущему .*?
съесть заключительный не комментарий; однако при этом продвигается с 1-символьным соответствием снова и снова до конца файла, что усложняет имхо следующий пункт 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;
}