簡體   English   中英

從文件中刪除評論

[英]Remove comments from file

我有這樣的文本文件

/* 
This is a comment 
I a looking to delete it
*/
//CALCULATE;     
Language([Dim Currency].[Currency].&[4]) = 2057;     
Language([Dim Currency].[Currency].&[2]) = 2067;  

我試過這段代碼

var newLines = oldLines.Select(line => new { 
                Line = line, 
                Words = line.Split("/*") 
            })
            .Where(lineInfo => !lineInfo.Words.Contains(wordToDelete))
            .Select(lineInfo => lineInfo.Line);
var newLines1 = oldLines.Select(line => new { 
            Line = line, 
            Words = line.Split("*/") 
        })
        .Where(lineInfo => !lineInfo.Words.Contains(wordToDelete))
        .Select(lineInfo => lineInfo.Line);

代碼返回此

This is a comment 
I a looking to delete it
//CALCULATE;     
Language([Dim Currency].[Currency].&[4]) = 2057;     
Language([Dim Currency].[Currency].&[2]) = 2067;

如何修改我的LINQ以使結果看起來像這樣(沒有塊注釋):

   //CALCULATE;     
    Language([Dim Currency].[Currency].&[4]) = 2057;     
    Language([Dim Currency].[Currency].&[2]) = 2067;

這是Aggregate LINQ運算符的完美用例,因為您將字符串列表(將輸入文件拆分為單獨的行的結果)轉換為單個字符串,輸入文件沒有注釋塊。 在一般情況下,達到Aggregate時要減少列表單個值,或者您想從序列中的一個元素攜帶狀態到下(例如,一塊國家的那會是有用的,與我們隨身攜帶是“我們在評論塊嗎?”作為布爾值)。

在下面的查詢中,我做了一個簡化的假設,即開始和結束注釋將始終在他們自己的行上。 如果不是這種情況,那么Aggregate的主體變得更復雜,但基本上是相同的(您需要添加代碼來處理在“/ *”或“* /”上拆分行)。 這是一個滿足您需求的查詢:

var inComment = false; // start off assuming we're not in a comment
// assume lines is some IEnumerable<string> representing the lines of your file,
// perhaps from a call to File.ReadAllLines(<file name>)
var result = 
    lines.Aggregate(new System.Text.StringBuilder(),
                    (builder, line) => {
                         if (!inComment)
                             // more code here if "/*" isn't on its own line
                             inComment = line.StartsWith("/*");

                         if (inComment)
                         {
                             // more code here if "*/" isn't on its own line
                             inComment &= !line.StartsWith("*/");
                             return builder;
                         }

                         if (!inComment) builder.AppendLine(line);

                         return builder;
                     }).ToString();

為了簡化示例,我沒有在Aggregate方法中包含“我們處於注釋塊”狀態,而是關閉了變量inComment 閉在inComment可以通過改變的類型來除去AggregateTuple<Boolean StringBuilder>而不是StringBuilder ,因為它是在上述查詢),並使用Item1代替inCommentItem2代替builder


編輯:我沒有解釋Aggregate方法的主體,這可能是有價值的,特別是因為其他評論者使用正則表達式鏈接到SO問題。 首先,你不能用一個正則表達式刪除所有注釋塊,你必須使用正則表達式以及一些額外的邏輯; 鏈接的帖子中 ,這個附加邏輯由Regex.Replace方法提供。 這是一個比這里要求更重的解決方案。 相反,您需要一個具有兩種狀態的簡單狀態機:InComment和NotInComment。 當您處於InComment狀態時,檢查您所在的評論是否以當前行結束,如果是,則轉到NotInComment狀態。 當您處於NotInComment狀態時,檢查是否在當前行開始注釋。 如果是這樣,那么你跳過該行並移動InComment狀態。 如果沒有,則將該行添加到輸出中。 InComment狀態由if (inComment)塊表示,NotInComment狀態是其他所有狀態。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM