Regex Match NC-Comments в строке со смешанным кодом C#
У меня есть текстовый файл со смешанным NC-Code и C#-Code. C#-Код начинается с "<#" и заканчивается "#>". Теперь мне нужно одно выражение регулярного выражения, чтобы найти все NC-комментарии. Одна проблема состоит в том, что NC-Comments начинается с ";" поэтому у меня есть некоторые проблемы, чтобы отличить NC-Comment с ";" C# -Код.
Можно ли достичь этого только одним регулярным выражением?
; 1. NC-Comment
FUNCT_A;
FUNCT_B;
<# // C#-Code
int temp = 42;
string var = "hello"; // C#-Comment
#>
FUNCT_C ; 2. Comment
<# // C#-Code
for(int i = 0; i <10; i++)
{
Console.WriteLine(i.ToString());
}
#>
; 3. Comment
FUNCT_D;
Результат регулярного выражения должен быть {1. NC-Comment, 2. Комментарий, 3. Комментарий}
Я играл в Arround со следующими регулярными выражениями:
1.) (;(.*?)\r?\n) --> Finds all NC-Comments but also C#-Code as comment
2.) (#>.*?<#)|(#>.*) --> Finds all NC-Code except the first NC-Code fragment
3.) #>.+?(?=<#) --> Finds all NC-Code except the first and last NC-Code fragment
Одним из решений может быть добавление каждого "<#" в стек и извлечение каждого "#>" из этого стека. Таким образом, если стек пуст, то текущей строкой является NC-код. Далее я должен выяснить, является ли эта строка комментарием NC.
1 ответ
Я скорее делаю это без регулярных выражений:
public static List<string> GetNCComments(Stream stream)
{
using (StreamReader sr = new StreamReader(stream))
{
List<string> result = new List<string>();
bool inCS = false; // are we in C# code?
int c;
while ((c = sr.Read()) != -1)
{
if (inCS)
{
switch ((char)c)
{
case '#':
if (sr.Peek() == '>') // end of C# block
{
sr.Read();
inCS = false;
}
break;
case '/':
if (sr.Peek() == '/') // a C# comment
sr.ReadLine(); // skip the whole comment
break;
}
}
else
{
switch ((char)c)
{
case '<':
if (sr.Peek() == '#') // start of C# block
{
sr.Read();
inCS = true;
}
break;
case ';': // NC comment
string comment = sr.ReadLine();
if (!string.IsNullOrEmpty(comment))
result.Add(comment);
break;
}
}
}
return result;
}
}
Использование:
var comments = GetNCComments(new FileStream(filePath, FileMode.Open, FileAccess.Read));
Код прост и понятен. Это также обрабатывает комментарии C#, но не строки C#. Я имею в виду, это работает правильно, если у вас есть #>
в комментарии C#. Но не работает, если у вас то же самое в строке C# (неправильно считает ее концом блока C#). Обработка этого случая также проста.