2009-12-28 20 views
9

Por ejemplo, me gustaría separar:Cómo separar carácter y número de parte de la cadena

  • OS234 a OS y 234
  • AA4230 a AA y 4230

he utilizado después trivial solución, pero estoy bastante seguro de que debería haber una solución más eficiente y robusta.

private void demo() 
    { string cell="ABCD4321"; 
     int a = getIndexofNumber(cell); 
     string Numberpart = cell.Substring(a, cell.Length - a); 
     row = Convert.ToInt32(rowpart); 
     string Stringpart = cell.Substring(0, a); 
    } 

private int getIndexofNumber(string cell) 
     { 
      int a = -1, indexofNum = 10000; 
      a = cell.IndexOf("0"); if (a > -1) { if (indexofNum > a) { indexofNum = a; } } 
      a = cell.IndexOf("1"); if (a > -1) { if (indexofNum > a) { indexofNum = a; } } 
      a = cell.IndexOf("2"); if (a > -1) { if (indexofNum > a) { indexofNum = a; } } 
      a = cell.IndexOf("3"); if (a > -1) { if (indexofNum > a) { indexofNum = a; } } 
      a = cell.IndexOf("4"); if (a > -1) { if (indexofNum > a) { indexofNum = a; } } 
      a = cell.IndexOf("5"); if (a > -1) { if (indexofNum > a) { indexofNum = a; } } 
      a = cell.IndexOf("6"); if (a > -1) { if (indexofNum > a) { indexofNum = a; } } 
      a = cell.IndexOf("7"); if (a > -1) { if (indexofNum > a) { indexofNum = a; } } 
      a = cell.IndexOf("8"); if (a > -1) { if (indexofNum > a) { indexofNum = a; } } 
      a = cell.IndexOf("9"); if (a > -1) { if (indexofNum > a) { indexofNum = a; } } 

      if (indexofNum != 10000) 
      { return indexofNum; } 
      else 
      { return 0; } 


     } 

Respuesta

1

He utilizado la respuesta de bniwredyc obtener la versión mejorada de mi rutina:

private void demo() 
     { 
      string cell = "ABCD4321"; 
      int row, a = getIndexofNumber(cell); 
      string Numberpart = cell.Substring(a, cell.Length - a); 
      row = Convert.ToInt32(Numberpart); 
      string Stringpart = cell.Substring(0, a); 
     } 

     private int getIndexofNumber(string cell) 
     { 
      int indexofNum=-1; 
      foreach (char c in cell) 
      { 
       indexofNum++; 
       if (Char.IsDigit(c)) 
       { 
        return indexofNum; 
       } 
      } 
      return indexofNum; 
     } 
5

utilizar LINQ para hacer esto

string str = "OS234"; 

var digits = from c in str 
      select c 
      where Char.IsDigit(c); 

var alphas = from c in str 
      select c 
      where !Char.IsDigit(c); 
+0

+1 solución limpia –

+2

Esto parece ser una buena solución, pero por desgracia .NET 2.0 usuarios no podía usar LINQ – Thunder

+0

Lo recomiendo - migrar a C# 3.0. –

15

expresiones regulares son los más adecuados para este tipo de trabajo:

using System.Text.RegularExpressions; 

Regex re = new Regex(@"([a-zA-Z]+)(\d+)"); 
Match result = re.Match(input); 

string alphaPart = result.Groups[1].Value; 
string numberPart = result.Groups[2].Value; 
+1

Puede agregar dos líneas a esta respuesta: cadena alphaPart = result.Groups [1]; string numberPart = result.Groups [2]; –

+0

Lo que sigue parece ser una solución más completa: Regex re = new Regex (@ "([a-zA-Z] +) (\ d +)"); Resultado de la coincidencia = re.Match ("as23"); cadena alphaPart = result.Groups [1] .ToString(); string numberPart = result.Groups [2] .ToString(); – Thunder

+1

¿No es 'result.Groups [1] .Value'? –

3

cada uno y su madre le dará una solución utilizando expresiones regulares, por lo aquí hay uno que no es:

// s is string of form ([A-Za-z])*([0-9])* ; char added 
int index = s.IndexOfAny(new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }); 
string chars = s.Substring(0, index); 
int num = Int32.Parse(s.Substring(index)); 
1

¿Lo hace con fines de clasificación? Si es así, tenga en cuenta que Regex puede matar el rendimiento de listas grandes. Con frecuencia uso un AlphanumComparer que es una solución general a este problema (puede manejar cualquier secuencia de letras y números en cualquier orden). Creo que lo he adaptado desde this page.

Incluso si no está ordenando, usar el enfoque carácter por carácter (si tiene longitudes variables) o una subcadena/análisis (si son fijos) será mucho más eficiente y más fácil de prueba que una Regex.

1

.NET 2.0 compatible, sin expresiones regulares

public class Result 
{ 
    private string _StringPart; 
    public string StringPart 
    { 
     get { return _StringPart; } 
    } 

    private int _IntPart; 
    public int IntPart 
    { 
     get { return _IntPart; } 
    } 

    public Result(string stringPart, int intPart) 
    { 
     _StringPart = stringPart; 
     _IntPart = intPart; 
    } 
} 

class Program 
{ 
    public static Result GetResult(string source) 
    { 
     string stringPart = String.Empty; 
     int intPart; 
     var buffer = new StringBuilder(); 
     foreach (char c in source) 
     { 
      if (Char.IsDigit(c)) 
      { 
       if (stringPart == String.Empty) 
       { 
        stringPart = buffer.ToString(); 
        buffer.Remove(0, buffer.Length); 
       } 
      } 

      buffer.Append(c); 
     } 

     if (!int.TryParse(buffer.ToString(), out intPart)) 
     { 
      return null; 
     } 

     return new Result(stringPart, intPart); 
    } 

    static void Main(string[] args) 
    { 
     Result result = GetResult("OS234"); 
     Console.WriteLine("String part: {0} int part: {1}", result.StringPart, result.IntPart); 
     result = GetResult("AA4230 "); 
     Console.WriteLine("String part: {0} int part: {1}", result.StringPart, result.IntPart); 
     result = GetResult("ABCD4321"); 
     Console.WriteLine("String part: {0} int part: {1}", result.StringPart, result.IntPart); 
     Console.ReadKey(); 
    } 
} 
+0

¡Parece bastante ingenioso! –

+0

@this .__ curious_geek yep. Me gusta la solución de Jasons. – bniwredyc

-1

uso Split a cadena seprate de picar esa pestaña uso \ t y el espacio

string s = "sometext\tsometext\tsometext"; 
string[] split = s.Split('\t'); 

ahora tiene una matriz de cadena que desea demasiado fácil

0

Si desea resolver más ocurrencias de carbón seguido por el número o viceversa puede utilizar

private string SplitCharsAndNums(string text) 
{ 
    var sb = new StringBuilder(); 
    for (var i = 0; i < text.Length - 1; i++) 
    { 
     if ((char.IsLetter(text[i]) && char.IsDigit(text[i+1])) || 
      (char.IsDigit(text[i]) && char.IsLetter(text[i+1]))) 
     { 
      sb.Append(text[i]); 
      sb.Append(" "); 
     } 
     else 
     { 
      sb.Append(text[i]); 
     } 
    } 

    sb.Append(text[text.Length-1]); 

    return sb.ToString(); 
} 

Y luego

var text = SplitCharsAndNums("asd1 asas4gr5 6ssfd"); 
var tokens = text.Split(' '); 
0

me gusta mucho jason's answer. No necesitamos expresiones regulares aquí. Mi solución para manejar entradas como "H1N1":

public static IEnumerable<string> SplitAlpha(string input) 
{ 
    var words = new List<string> { string.Empty }; 
    for (var i = 0; i < input.Length; i++) 
    { 
     words[words.Count-1] += input[i]; 
     if (i + 1 < input.Length && char.IsLetter(input[i]) != char.IsLetter(input[i + 1])) 
     { 
      words.Add(string.Empty); 
     } 
    } 
    return words; 
} 

Esta solución es lineal (O (n)).

ouput

"H1N1" -> ["H", "1", "N", "1"] 
"H" -> ["H"] 
"GH1N12" -> ["GH", "1", "N", "12"] 
"OS234" -> ["OS", "234"] 
Cuestiones relacionadas