2010-03-02 35 views
84

Tengo una variable String (básicamente una frase en inglés con un número no especificado de números) y me gustaría extraer todos los números en una matriz de enteros. Me preguntaba si había una solución rápida con expresiones regulares.¿Cómo extraer números de una cadena y obtener una matriz de enteros?


que utiliza la solución de Sean y cambió ligeramente:

LinkedList<String> numbers = new LinkedList<String>(); 

Pattern p = Pattern.compile("\\d+"); 
Matcher m = p.matcher(line); 
while (m.find()) { 
    numbers.add(m.group()); 
} 
+1

son números rodeados por espacios u otros caracteres? ¿Cómo se formatean los números, son hexadecimales, octales, binarios, decimales? –

+0

Pensé que estaba claro por la pregunta: es una oración en inglés con números. Además, estaba hablando de una matriz de enteros, así que lo que estaba buscando eran enteros. –

Respuesta

141
Pattern p = Pattern.compile("-?\\d+"); 
Matcher m = p.matcher("There are more than -2 and less than 12 numbers here"); 
while (m.find()) { 
    System.out.println(m.group()); 
} 

... impresiones -2 y 12.


-? coincide con un signo negativo principal - opcionalmente. \ d coincide con un dígito, y necesitamos escribir \ como \\ en Java String. Entonces, \ d + coincide con 1 o más dígitos.

+4

¿Podría complementar su respuesta explicando su expresión regular, por favor? – OscarRyz

+3

-? coincide con un signo negativo principal - opcionalmente. \ d coincide con un dígito, y tenemos que escribir \ as \\ en Java String. Entonces, \\ d + coincide con 1 o más dígitos –

+6

Cambié mi expresión a Pattern.compile ("-? [\\ d \\.] +") Para admitir flotantes. ¡Definitivamente me guiaste en el camino, Thx! – jlengrand

3

para los números racionales utilizar éste: (([0-9]+.[0-9]*)|([0-9]*.[0-9]+)|([0-9]+))

+1

El OP dijo números enteros, no números reales. Además, olvidaste escapar de los puntos, y ninguno de esos paréntesis es necesario. –

17
Pattern p = Pattern.compile("[0-9]+"); 
Matcher m = p.matcher(myString); 
while (m.find()) { 
    int n = Integer.parseInt(m.group()); 
    // append n to list 
} 
// convert list to array, etc 

En realidad se puede sustituir [0-9] con \ d, pero que supone el doble barra invertida de escape, lo que hace que sea más difícil de leer.

+0

Whoops.Sean maneja números negativos, así que eso es una mejora. – sidereal

+2

el suyo también manejará los números negativos si usa "-? [0-9] +" – cegprakash

7
StringBuffer sBuffer = new StringBuffer(); 
    Pattern p = Pattern.compile("[0-9]+.[0-9]*|[0-9]*.[0-9]+|[0-9]+"); 
    Matcher m = p.matcher(str); 
    while (m.find()) { 
    sBuffer.append(m.group()); 
    } 
    return sBuffer.toString(); 

Esto es para extraer los números de retención del punto decimal

0

que sugeriría para comprobar los valores ASCII para extraer números de una cadena Suponga que tiene una cadena entrada como myname12345 y si sólo quiere extraer los números 12345, puede hacerlo mediante la conversión de la cadena primero a matriz de caracteres continuación, utilizar el siguiente psuedocode

for(int i=0;i<CharacterArray.length;i++) 
    { 
    if(a[i]>=48&&a[i]<=58) 
      System.out.print(a[i]); 
    } 

una vez que los números se extraen de ellos anexan a una matriz

espero que esto ayude

+0

Una secuencia de Java se cuenta como una secuencia de unidades de código Unicode/UTF-16. Por el diseño de UTF-16, los primeros 128 caracteres tienen el mismo valor (no del mismo tamaño) que su codificación ASCII; Más allá de eso, pensar que estás tratando con ASCII dará lugar a errores. –

+0

@TomBlodget gracias por sus comentarios valiosos –

35

¿Qué hay de utilizar replaceAll método java.lang.String:

String str = "qwerty-1qwerty-2 455 f0gfg 4";  
    str = str.replaceAll("[^-?0-9]+", " "); 
    System.out.println(Arrays.asList(str.trim().split(" "))); 

Salida:

[-1, -2, 455, 0, 4] 

Descripción

[^-?0-9]+ 
  • + Entre uno y número ilimitado de veces, tantas veces como sea posible, dando la espalda, según sea necesario
  • -? Uno de los caracteres “-?”
  • 0-9 Un personaje en el rango entre‘0’y‘9’
+3

¿Por qué le gustaría mantener los signos de interrogación? Además, esto trata '-' en sí mismo como un número, junto con cosas como' 9-',' --- 6' y '1-2-3'. –

+0

Una muy buena alternativa sin usar las bibliotecas de importación;) –

2

La respuesta aceptada detecta dígitos, pero no detecta los números formateados, por ejemplo 2,000, ni decimales, p. 4.8. Para tal uso -?\\d+(,\\d+)*?\\.?\\d+?:

 Pattern p = Pattern.compile("-?\\d+(,\\d+)*?\\.?\\d+?"); 
     List<String> numbers = new ArrayList<String>(); 
     Matcher m = p.matcher("Government has distributed 4.8 million textbooks to 2,000 schools"); 
     while (m.find()) { 
      numbers.add(m.group()); 
     } 
     System.out.println(numbers); 

Salida: [4.8, 2,000]

+0

@JulienS .: No estoy de acuerdo. Esta expresión regular hace mucho más de lo que el OP solicitó, y lo hace incorrectamente. (Por lo menos, la porción decimal debería estar en un grupo opcional, con todo lo requerido y codicioso: '(?: \. \ D +)?'.) –

+0

Sin duda tiene un punto allí para la parte decimal. Sin embargo, es muy común encontrar números formateados. – Julien

+0

@AlanMoore muchos visitantes de SO están buscando formas diferentes para resolver problemas con diferencias/similitudes diferentes, y es útil que se hagan sugerencias. Incluso el OP podría haberse simplificado demasiado. –

0

8 Uso de Java, que puede hacer:

String str = "There 0 are 1 some -2-34 -numbers 567 here 890 ."; 
int[] ints = Arrays.stream(str.replaceAll("-", " -").split("[^-\\d]+")) 
       .filter(s -> !s.matches("-?")) 
       .mapToInt(Integer::parseInt).toArray(); 
System.out.println(Arrays.toString(ints)); // prints [0, 1, -2, -34, 567, 890] 

Si usted no tiene los números negativos, usted puede deshacerse de la replaceAll (y use !s.isEmpty() en filter), ya que eso es solo para dividir correctamente algo como 2-34 (esto también se puede manejar puramente con expresiones regulares en split, pero es bastante complicado).

Arrays.stream convierte nuestro String[] en un Stream<String>.

filter elimina las cadenas vacías iniciales y finales, así como cualquier - que no forme parte de un número.

mapToInt(Integer::parseInt).toArray() llama parseInt en cada String para darnos una int[].


Alternativamente, Java 9 tiene un método Matcher.results, lo que debería permitir algo así como:

Pattern p = Pattern.compile("-?\\d+"); 
Matcher m = p.matcher("There 0 are 1 some -2-34 -numbers 567 here 890 ."); 
int[] ints = m.results().map(MatchResults::group).mapToInt(Integer::parseInt).toArray(); 
System.out.println(Arrays.toString(ints)); // prints [0, 1, -2, -34, 567, 890] 

En la actualidad, ninguno de ellos es una gran mejora con respecto a solo bucle a través de los resultados con Pattern/Matcher como se muestra en las otras respuestas, pero debería ser más simple si desea seguir con operaciones más complejas que se simplifican significativamente con el uso de transmisiones.

0

me encontré con esta expresión más simple

String[] extractednums = msg.split("\\\\D++"); 
Cuestiones relacionadas