2010-08-26 64 views
5
string sentence = "X10 cats, Y20 dogs, 40 fish and 1 programmer."; 

string[] digits = Regex.Split (sentence, @"\D+"); 

para este código me sale valores en la matriz de dígitos como esto 10,20,40,1cómo hacer extraer número decimal de cadena en C#

string sentence = "X10.4 cats, Y20.5 dogs, 40 fish and 1 programmer."; 

string[] digits = Regex.Split (sentence, @"\D+"); 

para este código me sale valores en la matriz como dígitos esto 10,4,20,5,40,1

pero me gusta obtener 10.4,20.5,40,1 en números decimales, ¿cómo puedo hacer esto.

+0

me gusta la forma en que utiliza el ejemplo muy exacta de http://dotnetperls.com/regex-split – Wildhorn

+5

@Wildhorn - ¿Qué hay de malo en eso? Probablemente lo descubrió mientras buscaba una respuesta a su problema y notó que estaba cerca, pero no lo suficientemente cerca. –

Respuesta

20

pequeña mejora a @ solución de Michael:

// NOTES: about the LINQ: 
// .Where() == filters the IEnumerable (which the array is) 
//  (c=>...) is the lambda for dealing with each element of the array 
//  where c is an array element. 
// .Trim() == trims all blank spaces at the start and end of the string 
var doubleArray = Regex.Split(sentence, @"[^0-9\.]+") 
    .Where(c => c != "." && c.Trim() != ""); 

Devuelve:

10.4 
20.5 
40 
1 

La solución original fue devolver

[empty line here] 
10.4 
20.5 
40 
1 
. 
+2

. Donde (w =>! String.IsNullOrEmpty (w)) es más elegante. (> = .net 4) – Alexandre

+0

Esto no funciona con valores negativos. –

+0

@kami: eso se debe a que la expresión de expresiones regulares solo buscaba números positivos. Tendría que modificar la expresión regular para su situación. Sin embargo, mi respuesta fue específicamente (hace 7 años) dirigida a resolver el PO, y no para todas las situaciones. – code4life

0

Si tiene LINQ:

stringArray.Select(s=>decimal.Parse(s)); 

Un foreach también funcionaría. Es posible que deba comprobar que cada string es en realidad un número (.Parse no arroja una excepción).

+0

cómo obtengo el valor s – ratty

+0

s es la variable dentro del ámbito para la consulta de Linq. Es similar a decir foreach (string s en stringArray). –

5

tratar

Regex.Split (sentence, @"[^0-9\.]+") 
+1

Esto también le daría un falso positivo en un valor de 10.1.1.4. –

+1

¿El cursor (^) no lo niega? –

+0

@Daren Thomas, \ D igual [^ 0-9] –

1

Comprobar los lexers de sintaxis para la mayoría de los lenguajes de programación para una expresión regular para los decimales. Combina esa expresión regular con la cadena, encontrando todas las coincidencias.

0

Deberá permitir decimales en su expresión regular. Pruebe lo siguiente:

\d+(\.\d+)? 

Esto hará coincidir con los números en lugar de todo lo que no sean los números, sino que debe ser simple para iterar a través de los partidos para construir su matriz.

Algo a tener en cuenta es si también se debe buscar signos negativos, comas, etc.

4

decimal/flotante número extracción regex puede ser diferente dependiendo de si y qué mil separadores se utilizan, qué símbolo indica un separador decimal, si se desea también un exponente, si coincide o no con un positivo o negativo firmar, coincida o no con los números que pueden haber omitido 0, extraiga o no un número que termine con un separador decimal.

A regex genérico para que coincida con los tipos de números decimales más comunes se proporciona de Matching Floating Point Numbers with a Regular Expression:

[-+]?[0-9]*\.?[0-9]+(?:[eE][-+]?[0-9]+)? 

I sólo cambió el grupo de captura a un no capturar uno (añadido después de ?:().It matchesenter image description here

Si necesita para que sea aún más genérico, si el separador decimal puede ser un punto o una coma, reemplace \. con una clase de caracteres (o una expresión entre corchetes) [.,]:

[-+]?[0-9]*[.,]?[0-9]+(?:[eE][-+]?[0-9]+)? 
      ^^^^ 

Nota las expresiones anteriores coinciden con el número entero y los flotantes. única para que coincida con flotador/números decimales asegurarse de que el modelo parte fraccionaria es obligatorio mediante la eliminación de la segunda ? después \. (demo):

[-+]?[0-9]*\.[0-9]+(?:[eE][-+]?[0-9]+)? 
      ^

Ahora, 34 no se corresponde: enter image description here se empareja.

Si no desea hacer coincidir los números de flotación sin ceros a la izquierda (como .5) hacer la primera coincidencia de patrones dígitos obligatoria (mediante la adición de + cuantificador, para que coincida con 1 o más ocurrencias de dígitos):

[-+]?[0-9]+\.[0-9]+(?:[eE][-+]?[0-9]+)? 
     ^

Ver this demo. Ahora, que coincide mucho menos muestras: enter image description here

Ahora, lo que si usted no desea hacer coincidir <digits>.<digits> dentro <digits>.<digits>.<digits>.<digits>? ¿Cómo combinarlos como palabras completas? Utilice lookarounds:

[-+]?(?<!\d\.)\b[0-9]+\.[0-9]+(?:[eE][-+]?[0-9]+)?\b(?!\.\d) 

Y un demo here:

enter image description here

Ahora, qué pasa con los flotadores que tienen separadores de miles, como 12 123 456.23 o 34,345,767.678? Puede añadir (?:[,\s][0-9]+)* después de la primera [0-9]+ a cero o más secuencias de una coma o un espacio en blanco seguido con 1+ dígitos:

[-+]?(?<![0-9]\.)\b[0-9]+(?:[,\s][0-9]+)*\.[0-9]+(?:[eE][-+]?[0-9]+)?\b(?!\.[0-9]) 

Véase el regex demo: Intercambiar

enter image description here

con una coma \. si necesita usar una coma como separador decimal y un período como separador de miles.

Ahora, ¿cómo usar estos patrones en C#?

var results = Regex.Matches(input, @"<PATTERN_HERE>") 
     .Cast<Match>() 
     .Select(m => m.Value) 
     .ToList(); 
+0

Gracias por su respuesta. Esto no funcionaría para cadenas como "1,000,000.20" o "1,000,000,20". – joanfihu

+0

@joanfihu [Funciona para '1,000,000.20', pero ciertamente no para' 1,000,000,20'] (https://regex101.com/r/YFGJAe/1) ya que estos no deben usarse en el mismo contexto ya que el segundo no sigue el formato numérico de los EE. UU. Necesita cambiar manualmente la expresión para usar períodos como símbolos de agrupación de dígitos y comas como separador decimal. –

+0

Gracias. El primer ejemplo funciona con la última expresión regular. Utilicé el que funciona con comas y puntos. ¿Qué utilizarías para detectar el formato de los números? Necesito que funcione en el formato de Estados Unidos y el Reino Unido y el resto del mundo. – joanfihu

Cuestiones relacionadas