【问题标题】:C#/.NET string magic to remove comment lines from text file input?C#/.NET 字符串魔术从文本文件输入中删除注释行?
【发布时间】:2016-01-21 14:15:23
【问题描述】:

假设你有一个作为长字符串读入的文本文件:

123 123 123
123 123 123
// Just a comment
123 123 123    
123 123 123
# Just a comment
123 123 123

您通常将其拆分为类似这样的行,(Unity3D 中的示例),

    List<string> lines = new List<string>(
        controlFile.text.Split(new string[] { "\r","\n" }, 
        StringSplitOptions.RemoveEmptyEntries));

.NET 提供了不可思议的字符串魔法,例如格式化等等。

我想知道,是否有一些可用的魔法可以轻松删除 cmets?

注意 - 当然可以使用正则表达式等来做到这一点。正如 SonerGönül 指出的那样,它可以通过 .Where.StartsWith 有效地完成

我的问题是,在 .NET 字符串魔术的世界中是否有一些工具,专门“理解”并帮助 cmets

即使专家的回答是“绝对不”,这也是一个有用的答案。

【问题讨论】:

  • 问题是每种格式对 cme​​ts 使用不同的分隔符。因此,需要对该方法进行参数化以接受您的注释分隔符类型。在您的示例中,您显示了两个。还有更多的可能性吗?还是只有那两个?
  • 注释行有哪些可能性?仅以//# 开头?如果是这样,您可以使用类似.Where(line =&gt; !line.StartsWith("//") || !line.StartsWith("#")) 的东西吗?
  • 另外一个重要的问题是你需要支持inline cmets,还是我们可以假设注释在行首,整行都可以去掉?
  • lines.Where(l =&gt; !l.StartsWith("//"))
  • 你是在问解析成行,还是在你有一堆行后删除 cmets? (或两者兼而有之?)

标签: c# .net string linq


【解决方案1】:

你可以这样试试:

var t= Path.GetTempFileName();
var l= File.ReadLines(fileName).Where(l => !l.StartsWith("//") || !l.StartsWith("#"));
File.WriteAllLines(t, l);
File.Delete(fileName);
File.Move(t, fileName);

因此,您基本上可以将原始文件的内容复制到没有 cmets 行的临时文件中。然后删除文件并将临时文件移动到原始文件。

【讨论】:

  • 多行cmets会导致这个问题^
  • @FᴀʀʜᴀɴAɴᴀᴍ 我的意思是,这只适用于示例中显示的 cmets 类型。这个问题是难以置信地本地化的,主要是因为对正在处理的文件的内容做了很多假设。根据问题中提供给我们的当前信息量,这个答案在各个方面都是完整的。
  • 这也将删除#region / #endregion 指令,这可能需要也可能不需要。
  • 不应该是l =&gt; !l.StartsWith("//") &amp;&amp; !l.StartsWith("#")吗?或者l =&gt; !(l.StartsWith("//") || l.StartsWith("#")) 一行不能同时以//# 开头。
  • 我也可能会考虑在被检查的行上调用 Trim() 或 TrimStart() 以删除行前的任何空白
【解决方案2】:

希望这是有道理的:

 string[] comments = { "//", "'", "#" };
 var CommentFreeText = File.ReadLines("fileName Here")
                       .Where(X => !comments.Any(Y => X.StartsWith(Y)));

您可以使用要从 textFile 中删除的注释符号填充 comments[]。在阅读文本时,它将消除以任何注释符号开头的所有行。

您可以使用以下方法将其写回:

File.WriteAllLines("path", CommentFreeText);

【讨论】:

    【解决方案3】:

    仅供参考,Rahul 基于 SonerGönül 的答案是错误的,代码有错误并且无法正常工作。

    为了节省任何人的输入,这里有一个功能性/经过测试的答案,它只使用匹配。

    关于手头的问题,似乎 没有 .Net 内置任何“理解”文本中典型 cmets 的特定内容。您只需要使用这样的匹配从头开始编写它...

    // ExtensionsSystem.cs, your handy system-like extensions
    using UnityEngine;
    using System.Collections.Generic;
    using System;
    using System.Text.RegularExpressions;
    using System.Linq;
    
    public static class ExtensionsSystem
        {
        public static List<string> CleanLines(this string stringFromFile)
            {
            List<string> result = new List<string>(
                stringFromFile
                .Split(new string[] { "\r","\n" },
                    StringSplitOptions.RemoveEmptyEntries)
                );
    
            result = result
                .Where(line => !(line.StartsWith("//")
                                || line.StartsWith("#")))
                .ToList();
    
            return result;
            }
        }
    

    然后你会

    List<string> lines = controlFile.text.CleanLines();
    foreach (string ln in lines) Debug.Log(ln);
    

    【讨论】:

    • 这与已经给出的其他两个答案有何不同?
    猜你喜欢
    • 1970-01-01
    • 2017-01-19
    • 2014-04-22
    • 1970-01-01
    • 1970-01-01
    • 2010-12-18
    • 2014-12-19
    • 2021-01-04
    相关资源
    最近更新 更多