2009-02-06 6 views

Respuesta

1
result = originalString.Split(separator); 
for(int i = 0; i < result.Length - 1; i++) 
    result[i] += separator; 

(EDITAR - esto es una mala respuesta - leí mal la pregunta y no vi que era la división de múltiples caracteres.)

(EDITAR - una versión correcta de LINQ es torpe, . dado que el separador no deben recibir concatenado en la cadena final de la matriz dividida)

+0

Esto solo funciona si hay un solo separador. Es posible que necesite emplear magia regex. –

+0

Eso es verdad. Lo siento, no leí bien la pregunta. – mquander

1

hace poco escribió un método de extensión hacer esto:

public static class StringExtensions 
    { 
     public static IEnumerable<string> SplitAndKeep(this string s, string seperator) 
     { 
      string[] obj = s.Split(new string[] { seperator }, StringSplitOptions.None); 

      for (int i = 0; i < obj.Length; i++) 
      { 
       string result = i == obj.Length - 1 ? obj[i] : obj[i] + seperator; 
       yield return result; 
      } 
     } 
    } 
0

Regex.Split parece que podría hacer lo que quiera, tal vez.

127

Si los caracteres eran divididas ,, ., y ;, que iba a tratar:

string[] parts = Regex.Split(originalString, @"(?<=[.,;])") 

(?<=PATTERN) es positivo aspecto subyacente para PATTERN. Debe coincidir en cualquier lugar donde el texto anterior se ajuste a PATTERN, por lo que debe haber una coincidencia (y una división) después de cada aparición de cualquiera de los caracteres.

+16

Esto funcionó muy bien para mí - ¡Gracias! Solo tuve que hacer un pequeño ajuste para mis propósitos, ya que quería incluir el delimitador al principio de cada línea (no al final). Use @ "(? = [.,;])" En su lugar. – MikeTeeVee

+2

Esta respuesta debe aceptarse para que sea más fácil acceder. Soy un usuario experimentado de SO y me llevó un tiempo encontrarlo. –

+0

Hi @ it-depends Me gusta su respuesta, pero ¿qué ocurre si quiero dividirla usando cadenas en su lugar? Por ejemplo, todos los separadores que está utilizando pero seguidos de un espacio en blanco. Lo he intentado pero no funciona. @ "(? <= [.,;])" –

0
using System.Collections.Generic; 
using System.Text.RegularExpressions; 

namespace ConsoleApplication9 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string input = @"This;is:a.test"; 
      char sep0 = ';', sep1 = ':', sep2 = '.'; 
      string pattern = string.Format("[{0}{1}{2}]|[^{0}{1}{2}]+", sep0, sep1, sep2); 
      Regex regex = new Regex(pattern); 
      MatchCollection matches = regex.Matches(input); 
      List<string> parts=new List<string>(); 
      foreach (Match match in matches) 
      { 
       parts.Add(match.ToString()); 
      } 
     } 
    } 
} 
1

Iterar a través de la cadena de caracteres por el personaje (que es lo expresiones regulares hace de todos modos. Cuando encuentre un divisor, y luego escindir una subcadena.

pseudo código

int hold, counter; 
List<String> afterSplit; 
string toSplit 

for(hold = 0, counter = 0; counter < toSplit.Length; counter++) 
{ 
    if(toSplit[counter] = /*split charaters*/) 
    { 
     afterSplit.Add(toSplit.Substring(hold, counter)); 
     hold = counter; 
    } 
} 

Eso es una especie de C#, pero no realmente. Obviamente, elija los nombres de función apropiados. Además, creo que podría haber un error "por-1" allí.

Pero eso hará lo que estás pidiendo.

2

Esto parece funcionar, pero no se ha probado mucho.

public static string[] SplitAndKeepSeparators(string value, char[] separators, StringSplitOptions splitOptions) 
{ 
    List<string> splitValues = new List<string>(); 
    int itemStart = 0; 
    for (int pos = 0; pos < value.Length; pos++) 
    { 
     for (int sepIndex = 0; sepIndex < separators.Length; sepIndex++) 
     { 
      if (separators[sepIndex] == value[pos]) 
      { 
       // add the section of string before the separator 
       // (unless its empty and we are discarding empty sections) 
       if (itemStart != pos || splitOptions == StringSplitOptions.None) 
       { 
        splitValues.Add(value.Substring(itemStart, pos - itemStart)); 
       } 
       itemStart = pos + 1; 

       // add the separator 
       splitValues.Add(separators[sepIndex].ToString()); 
       break; 
      } 
     } 
    } 

    // add anything after the final separator 
    // (unless its empty and we are discarding empty sections) 
    if (itemStart != value.Length || splitOptions == StringSplitOptions.None) 
    { 
     splitValues.Add(value.Substring(itemStart, value.Length - itemStart)); 
    } 

    return splitValues.ToArray(); 
} 
20

Construido a partir de la respuesta de bfree, que tenía el mismo objetivo, pero quería dividir en una serie de caracteres similares al método división original, y también tengo múltiples fracturas por cadena:

public static IEnumerable<string> SplitAndKeep(this string s, char[] delims) 
{ 
    int start = 0, index; 

    while ((index = s.IndexOfAny(delims, start)) != -1) 
    { 
     if(index-start > 0) 
      yield return s.Substring(start, index - start); 
     yield return s.Substring(index, 1); 
     start = index + 1; 
    } 

    if (start < s.Length) 
    { 
     yield return s.Substring(start); 
    } 
} 
+0

+1 Incluye el delimitador en un índice de matriz, ya que sonaba como el OP deseado. –

+0

No hay razón en particular, simplemente no vi una operación de 'intercambio' simple disponible. Podría ser reemplazado por muchos de los métodos alternativos de intercambio. – esac

+1

if (inicio Marko

0

código Java:

public static class String_Ext 
{ 
    public static string[] SplitOnGroups(this string str, string pattern) 
    { 
     var matches = Regex.Matches(str, pattern); 
     var partsList = new List<string>(); 
     for (var i = 0; i < matches.Count; i++) 
     { 
      var groups = matches[i].Groups; 
      for (var j = 0; j < groups.Count; j++) 
      { 
       var group = groups[j]; 
       partsList.Add(group.Value); 
      } 
     } 
     return partsList.ToArray(); 
    } 
} 

var parts = "abcde \tfgh\tikj\r\nlmno".SplitOnGroups(@"\s+|\S+"); 

for (var i = 0; i < parts.Length; i++) 
    Print(i + "|" + Translate(parts[i]) + "|"); 

salida:

0|abcde| 
1| \t| 
2|fgh| 
3|\t| 
4|ikj| 
5|\r\n| 
6|lmno| 
17

Sólo en caso de que alguien quiere que esto aswell respuesta ...

En lugar de string[] parts = Regex.Split(originalString, @"(?<=[.,;])") usted podría utilizar string[] parts = Regex.Split(originalString, @"(?=yourmatch)") donde yourmatch es lo que su separación es.

Suponiendo que la cadena original era

777- gato

777 - perro

777 - ratón

777 - rata

777 - lobo

Regex.Split(originalString, @"(?=777)") haría devolver

777 - gato

777 - perro

y así sucesivamente

+0

sí, impresionante, esto mantiene el delimitador, gracias –

+0

¿Cómo se especifica una lista de delimitadores? es decir, "777, 666, etc." – Thomas

+1

@Thomas si no me equivoco, podría usar el token '|' para especificar alternativas. Entonces sería como: '(? = 777 | 666)' –

1

Una gran cantidad de respuestas a esto! Uno que noqueé para dividirlo por varias cuerdas (la respuesta original es solo para caracteres, es decir, longitud de 1). Esto no ha sido probado completamente.

public static IEnumerable<string> SplitAndKeep(string s, params string[] delims) 
{ 
    var rows = new List<string>() { s }; 
    foreach (string delim in delims)//delimiter counter 
    { 
     for (int i = 0; i < rows.Count; i++)//row counter 
     { 
      int index = rows[i].IndexOf(delim); 
      if (index > -1 
       && rows[i].Length > index + 1) 
      { 
       string leftPart = rows[i].Substring(0, index + delim.Length); 
       string rightPart = rows[i].Substring(index + delim.Length); 
       rows[i] = leftPart; 
       rows.Insert(i + 1, rightPart); 
      } 
     } 
    } 
    return rows; 
} 
Cuestiones relacionadas