【问题标题】:C#: How do I prepend text to each line in a string?C#:如何将文本添加到字符串中的每一行?
【发布时间】:2009-09-23 15:47:18
【问题描述】:

“MagicFunction”的实现是什么样子才能使以下 (nunit) 测试通过?

public MagicFunction_Should_Prepend_Given_String_To_Each_Line()
{
    var str = @"line1
line2
line3";

    var result = MagicFunction(str, "-- ");

    var expected = @"-- line1
-- line2
-- line3";

    Assert.AreEqual(expected, result);
}

【问题讨论】:

    标签: c# string implementation


    【解决方案1】:
    string MagicFunction(string str, string prepend)
    {
       str = str.Replace("\n", "\n" + prepend);
       str = prepend + str;
       return str;
    }
    

    编辑:
    正如其他人指出的那样,换行符因环境而异。如果您只打算在同一环境中创建的文件上使用此功能,那么 System.Environment 将正常工作。但是,如果您在 Linux 机器上创建文件,然后将其传输到 Windows 机器,您将需要指定不同类型的换行符。由于 Linux 使用 \n 而 Windows 使用 \r\n 这段代码适用于 Windows 和 Linux 文件。如果您将 Mac 加入其中 (\r),您将不得不想出一些更复杂的东西。

    【讨论】:

    • “\r”字符呢?
    • 或者更好的是,Environment.NewLine 怎么样。我很确定这就是它的用途。 :)
    • @SpencerRuport 替换应该是 Replace (坦率地说,不可能建议编辑少于 6 个字符)
    • @wondra - 已修复!谢谢。
    【解决方案2】:
    private static string MagicFunction(string str, string prefix)
    {
        string[] lines = str.Split(new[] { '\n' });
        return string.Join("\n", lines.Select(s => prefix + s).ToArray());
    }
    

    【讨论】:

    • 您可能需要考虑 \r\n - var lines = str.Split(new char[] {'\r','\n'}, StringSplitOptions.RemoveEmptyEntries);
    • @Gishu:我使用\r\n\n 换行符测试了该方法,并且两者都适用。它不适用于仅\r。仅在 \n 上拆分的一个好处是生成的字符串包含与输入相同的样式换行符(即使在字符串中 \r\n\n 换行符之间存在混合。
    【解决方案3】:

    怎么样:

    string MagicFunction(string InputText) {
        public static Regex regex = new Regex(
              "(^|\\r\\n)",
            RegexOptions.IgnoreCase
            | RegexOptions.CultureInvariant
            | RegexOptions.IgnorePatternWhitespace
            | RegexOptions.Compiled
            );
    
        // This is the replacement string
        public static string regexReplace = 
              "$1-- ";
    
        // Replace the matched text in the InputText using the replacement pattern
        string result = regex.Replace(InputText,regexReplace);
    
        return result;
    }
    

    【讨论】:

      【解决方案4】:
      var result = "-- " + str.Replace(Environment.NewLine, Environment.NewLine + "-- ");
      

      如果你想让它处理 Windows (\r\n) NewLines 或 Unix 的 (\n) 那么:

      var result = "-- " + str.Replace("\n", "\n-- ");
      

      无需触摸 \r,因为它会留在原来的位置。但是,如果您想在 Unix 和 Windows 之间切换,那么:

      var result = "-- " + str.Replace("\r","").Replace("\n", Enviornment.NewLine + "-- ");
      

      会这样做并以本地操作系统的格式返回结果

      【讨论】:

      • @Thomas:Environment.NewLine 将适用于操作系统的 NewLine 字符串。唯一的问题是如果在 unix 上解析 windows 文件,反之亦然
      • 是的,这就是我要说的问题...在 Windows 上操作 UNIX 文件很常见,反之亦然
      【解决方案5】:

      你可以这样做:

      public string MagicFunction2(string str, string prefix)
      {
          bool first = true;
          using(StringWriter writer = new StringWriter())
          using(StringReader reader = new StringReader(str))
          {
              string line;
              while((line = reader.ReadLine()) != null)
              {
                  if (!first)
                      writer.WriteLine();
                  writer.Write(prefix + line);
                  first = false;
              }
              return writer.ToString();
          }
      }
      

      【讨论】:

      • 我刚刚尝试了 "\r\n" (Windows)、"\n" (Linux) 和 "\r" (Mac),它适用于所有情况。但是它不保留原始的换行标记,它总是在输出字符串中使用 Environment.NewLine
      • 嗯,小错误。它总是在字符串的末尾添加一个换行符,即使原始字符串没有。
      【解决方案6】:

      您可以通过 Environment.NewLine 拆分字符串,然后为每个字符串添加前缀,然后通过 Environment.NewLine 将它们连接起来。

      string MagicFunction(string prefix, string orignalString)
      {
          List<string> prefixed = new List<string>();
          foreach (string s in orignalString.Split(new[]{Environment.NewLine}, StringSplitOptions.None))
          {
              prefixed.Add(prefix + s);
          }
      
          return String.Join(Environment.NewLine, prefixed.ToArray());
      }
      

      【讨论】:

        【解决方案7】:

        这个怎么样。它使用 StringBuilder 以防您计划添加很多行。

        string MagicFunction(string input)
        {
          StringBuilder sb = new StringBuilder();
          StringReader sr = new StringReader(input);
          string line = null;
        
          using(StringReader sr = new StringReader(input))
          {
            while((line = sr.ReadLine()) != null)
            {
              sb.Append(String.Concat("-- ", line, System.Environment.NewLine));
            }
          }
          return sb.ToString();
        }
        

        【讨论】:

          【解决方案8】:

          感谢大家的回答。我将 MagicFunction 实现为扩展方法。它利用了 Thomas Levesque 的答案,但经过增强以处理所有主要环境,并假设您希望输出字符串使用与输入字符串相同的换行符终止符。

          我更喜欢 Thomas Levesque 的答案(优于 Spencer Ruport、Fredrik Mork、Lazarus 和 JDunkerley 的答案),因为它表现最好。我将在我的博客上发布性能结果,稍后为感兴趣的人提供链接。

          (显然,'MagicFunctionIO'的函数名称应该更改。我选择了'PrependEachLineWith')

          public static string MagicFunctionIO(this string self, string prefix)
          {
            string terminator = self.GetLineTerminator();
            using (StringWriter writer = new StringWriter())
            {
              using (StringReader reader = new StringReader(self))
              {
                bool first = true;
                string line;
                while ((line = reader.ReadLine()) != null)
                {
                  if (!first)
                    writer.Write(terminator);
                  writer.Write(prefix + line);
                  first = false;
                }
                return writer.ToString();
              }
            }
          }
          
          public static string GetLineTerminator(this string self)
          {
            if (self.Contains("\r\n")) // windows
              return "\r\n";
            else if (self.Contains("\n")) // unix
              return "\n";
            else if (self.Contains("\r")) // mac
              return "\r";
            else // default, unknown env or no line terminators
              return Environment.NewLine;
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2019-09-20
            • 2015-11-01
            • 2018-03-13
            • 1970-01-01
            • 2023-03-13
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多