Pergunta

O que seria uma implementação de look 'MagicFunction' como fazer o seguinte (nunit) passagem de teste?

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);
}
Foi útil?

Solução 8

Obrigado a todos por suas respostas. Implementei o MagicFunction como um método de extensão. Ele aproveita a resposta de Thomas Levesque, mas é reforçada para lidar com todos os principais ambientes e assume que você deseja que o string de saída para usar o mesmo terminador nova linha da cadeia de entrada.

I favoreceu a resposta de Thomas Levesque (mais de Spencer Ruport de, Fredrik Mork de Lázaro, e JDunkerley) porque foi o melhor desempenho. Vou postar os resultados de desempenho no meu blog e link aqui mais tarde para os interessados.

(Obviamente, o nome da função de 'MagicFunctionIO' deve ser mudado. Fui com '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;
}

Outras dicas

string MagicFunction(string str, string prepend)
{
   str = str.Replace("\n", "\n" + prepend);
   str = prepend + str;
   return str;
}

EDIT:
Como já foi salientado, os caracteres de nova linha variam entre os ambientes. Se você está planejando apenas para utilizar esta função em arquivos que foram criados no mesmo ambiente, em seguida, System.Environment irá funcionar bem. No entanto, se você criar um arquivo em uma caixa de Linux e depois transferi-la para um Windows caixa que você vai querer especificar um tipo diferente de nova linha. Desde usos Linux \ n e Windows usa \ r \ n este pedaço de código irá trabalhar para ambos os arquivos Windows e Linux. Se você está jogando Macs na mistura (\ r) você vai ter que vir com algo um pouco mais envolvidos.

private static string MagicFunction(string str, string prefix)
{
    string[] lines = str.Split(new[] { '\n' });
    return string.Join("\n", lines.Select(s => prefix + s).ToArray());
}

Como sobre: ??

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;
}
var result = "-- " + str.Replace(Environment.NewLine, Environment.NewLine + "-- ");

Se você quer lidar com o Windows (\ r \ n) novas linhas ou aqueles Unix (\ n), em seguida:

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

Não há necessidade de tocar o \ r como é para ser deixado onde estava antes. Se no entanto você quer cruzar entre o Unix e Windows, em seguida:

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

Irá fazê-lo e devolver o resultado no formato do SO local

Você poderia fazê-lo assim:

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();
    }
}

Você poderia dividir a string por Environment.NewLine, e depois adicionar o prefixo para cada um dos corda, e depois juntá-los por 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());
}

Como sobre isso. Ele usa StringBuilder no caso de você está pensando em prepending um monte de linhas.

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();
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top