0

NC コードと C# コードが混在するテキストファイルがあります。C# コードは "<#" で始まり "#>" で終わります。ここで、すべての NC コメントを検索するために 1 つの正規表現が必要です。問題の 1 つは、NC コメントが「;」で始まることです。したがって、NC コメントを「;」で区別するためにいくつかの問題が発生しました。C#コードの。

たった1つの正規表現でこれを達成することは可能ですか?

; 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-コメント、2.コメント、3.コメント}

私は次の正規表現で遊んだ:

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

解決策の 1 つは、各 "<#" をスタックにプッシュし、このスタックから各 "#>" をポップすることです。したがって、スタックが空の場合、現在の文字列は NC コードです。次に、この文字列が NC コメントかどうかを確認する必要があります。

4

1 に答える 1

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# コメントに aがある場合、正しく機能します。ただし、C# 文字列と同じものがある場合は機能しません (C# ブロックの末尾と誤って見なされます)。この場合の取り扱いも簡単です。

于 2013-03-21T18:47:43.630 に答える