Извлекать Enums с скобками в комментариях? - PullRequest
0 голосов
/ 23 января 2019

Enum, который я хочу извлечь, выглядит следующим образом:

...
other code 
...
enum A
{
  a,
  b=2,
  c=3,
  d//{x}
}
...
More Enums like the above.
...

Сначала я попытался использовать опцию Singleline с регулярным выражением:
enum\s*\w+\s*{.*?\}

Однако,так как комментарии имеют скобки. Регулярное выражение не работает.Он остановится, когда он перейдет к скобке в комментариях.

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

Затем я попытался разобрать скобки без комментариев вперед.
Подшаг - найти скобки после комментариев: (?m:^.*?//.*?}.*?$).

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

Затем я попытался использовать многострочный.Поскольку основная проблема заключается в квадратных скобках комментариев. Я пытался:
(?!//.*)} Отрицательный взгляд вперед не работает так, как я ожидал.

Вот ссылка csharp-regex-test-link для проверки.

Подводя итог, мне нужно разобрать enum из файла исходного кода csharp.

Основная проблема для меня - это квадратные скобки в комментариях.

Редактировать : Чтобы уточнить

1. скобки в комментариях попарно.Например:

xxx=xxx; //{xx} 

2.комментарии только в виде //

3. Я не могу полагаться на отступы.

Ответы [ 2 ]

0 голосов
/ 23 января 2019

Я не думаю, что можно выполнить вашу задачу с одним регулярным выражением. Что делать, если у вас есть строка, которая выглядит как

var notEnum = "enum A {a, b, c}";

Hovewer вы можете захватить свои перечисления с несколькими проходами. Взгляните на этот алгоритм

  1. Очистить содержимое строк
  2. Оставить однострочные комментарии
  3. Пропустить мультилинейные комментарии
  4. Используй свое оригинальное регулярное выражение

Пример:

var code = ...

var stringLiterals = new Regex("\"[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*\"", RegexOptions.Compiled);
var multilineComments = new Regex("/\\*.*?\\*/", RegexOptions.Compiled | RegexOptions.Singleline);
var singlelineComments = new Regex("//.*$", RegexOptions.Compiled | RegexOptions.Multiline);
var @enum = new Regex("enum\\s*\\w+\\s*{.*?}", RegexOptions.Compiled | RegexOptions.Singleline);

code = stringLiterals.Replace(code, m => "\"\"");
code = multilineComments.Replace(code, m => "");
code = singlelineComments.Replace(code, m => "");

var enums = @enum.Matches(code).Cast<Match>().ToArray();

foreach (var match in enums)
    Console.WriteLine(match.Value);
0 голосов
/ 23 января 2019

Вы можете использовать

@"\benum\s*\w+\s*{(?>[^{}]+|(?<o>){|(?<-o>)})*(?(o)(?!)|)}"

См. Демоверсию regex

Подробности

  • \benum- целое слово enum
  • \s* - 0+ пробелов
  • \w+ - 1+ слов символов
  • \s* - 0+ пробелов
  • { - { char
  • (?>[^{}]+|(?<o>){|(?<-o>)})* - либо 1+ символов, отличных от { и }, либо { с пустой строкой, вставленной в группу *Стек 1034 * или } со значением, извлеченным из группы * стек 1036 *
  • (?(o)(?!)|) - условная конструкция yes-no, которая не совпадает и возвращает движок регулярных выражений в текущее местоположение, если группаo все еще остаются в стеке
  • } - символ }.
...