Dividir uma string com delimitadores, mas manter os delimitadores no resultado em c #

Eu gostaria de dividir uma string com delimitadores, mas manter os delimitadores no resultado.

Como eu faria isso em c #?

Se você quiser que o delimitador seja seu “próprio split”, você pode usar o Regex.Split, por exemplo:

string input = "plum-pear"; string pattern = "(-)"; string[] substrings = Regex.Split(input, pattern); // Split on hyphens foreach (string match in substrings) { Console.WriteLine("'{0}'", match); } // The method writes the following to the console: // 'plum' // '-' // 'pear' 

Esta versão não usa LINQ ou Regex e, portanto, é relativamente eficiente. Eu acho que pode ser mais fácil de usar do que o Regex, porque você não precisa se preocupar em escaping de delimitadores especiais. Ele retorna um IList que é mais eficiente do que sempre convertendo para um array. É um método de extensão, o que é conveniente. Você pode passar os delimitadores como uma matriz ou como vários parâmetros.

 ///  /// Splits the given string into a list of substrings, while outputting the splitting /// delimiters (each in its own string) as well. It's just like String.Split() except /// the delimiters are preserved. No empty strings are output. /// String to parse. Can be null or empty. /// The delimiting characters. Can be an empty array. ///  public static IList SplitAndKeepDelimiters(this string s, params char[] delimiters) { var parts = new List(); if (!string.IsNullOrEmpty(s)) { int iFirst = 0; do { int iLast = s.IndexOfAny(delimiters, iFirst); if (iLast >= 0) { if (iLast > iFirst) parts.Add(s.Substring(iFirst, iLast - iFirst)); //part before the delimiter parts.Add(new string(s[iLast], 1));//the delimiter iFirst = iLast + 1; continue; } //No delimiters were found, but at least one character remains. Add the rest and stop. parts.Add(s.Substring(iFirst, s.Length - iFirst)); break; } while (iFirst < s.Length); } return parts; } 

Alguns testes unitários:

 text = "[a link|http://www.google.com]"; result = text.SplitAndKeepDelimiters('[', '|', ']'); Assert.IsTrue(result.Count == 5); Assert.AreEqual(result[0], "["); Assert.AreEqual(result[1], "a link"); Assert.AreEqual(result[2], "|"); Assert.AreEqual(result[3], "http://www.google.com"); Assert.AreEqual(result[4], "]"); 

Eu diria que a maneira mais fácil de realizar isso (exceto pelo argumento de Hans Kesting) é dividir a string da maneira normal, depois iterar sobre a matriz e adicionar o delimitador a cada elemento, exceto o último.

Eu queria fazer uma seqüência de múltiplas linhas como esta, mas precisava manter as quebras de linha, então eu fiz isso

 string x = @"line 1 {0} line 2 {1} "; foreach(var line in string.Format(x, "one", "two") .Split("\n") .Select(x => x.Contains('\r') ? x + '\n' : x) .AsEnumerable() ) { Console.Write(line); } 

rendimentos

 line 1 one line 2 two 

Eu me deparei com o mesmo problema, mas com vários delimitadores. Aqui está minha solução:

  public static string[] SplitLeft(this string @this, char[] delimiters, int count) { var splits = new List(); int next = -1; while (splits.Count + 1 < count && (next = @this.IndexOfAny(delimiters, next + 1)) >= 0) { splits.Add(@this.Substring(0, next)); @this = new string(@this.Skip(next).ToArray()); } splits.Add(@this); return splits.ToArray(); } 

Amostra com a separação dos nomes das variables ​​do CamelCase:

 var variableSplit = variableName.SplitLeft( Enumerable.Range('A', 26).Select(i => (char)i).ToArray()); 

Para evitar adicionar caractere à nova linha, tente isto:

  string[] substrings = Regex.Split(input,@"(?<=[-])");