我有一个这样的文本文件
/*
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
的主体会变得更复杂,但实际上是相同的(您需要添加代码以处理在“ / *”或“ * /”上的行拆分)。这是满足您需求的查询:
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
方法中包括“我们是否在注释块中”状态,而是在变量Aggregate
上关闭了状态。通过将inComment
的类型更改为inComment
(而不是上面的查询中的Aggregate
),并使用Tuple<Boolean StringBuilder>
代替StringBuilder
和Item1
,可以消除对inComment
的关闭。而不是Item2
。编辑:我没有解释
builder
方法的主体,这可能很有价值,特别是因为其他评论者使用正则表达式链接到SO问题。首先,您不能使用单个正则表达式删除所有注释块,而必须使用正则表达式以及一些其他逻辑。在linked post中,此附加逻辑由Aggregate
方法提供。这是比此处所需的解决方案重得多的解决方案。相反,您需要具有两个状态的简单状态机:InComment和NotInComment。当您处于InComment状态时,请检查您所在的注释是否在当前行结束,如果是,则转到NotInComment状态。处于NotInComment状态时,请检查注释是否在当前行开始。如果是这样,则跳过该行并移动InComment状态。如果不是,则将该行添加到输出中。 InComment状态由Regex.Replace
块表示,NotInComment状态是其他所有内容。关于c# - 从文件中删除评论,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22915612/