¿Cómo extraer números de una cadena y obtener una matriz de enteros?

Tengo una variable String (básicamente una oración en inglés con una cantidad no especificada 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.


Utilicé la solución de Sean y la cambié ligeramente:

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

 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 debemos escribir \ as \\ en una cadena de Java. Entonces, \ d + coincide con 1 o más dígitos.

Qué tal utilizar el método replaceAll 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 una y un número ilimitado de veces, tantas veces como sea posible, devolviéndola según sea necesario
  • -? Uno de los personajes “-?”
  • 0-9 Un personaje en el rango entre “0” y “9”
 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 puede reemplazar [0-9] con \ d, pero eso implica el doble escape de barra invertida, lo que hace que sea más difícil de leer.

  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 números que retienen el decimal

para números racionales usa este: (([0-9]+.[0-9]*)|([0-9]*.[0-9]+)|([0-9]+))

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

  Pattern p = Pattern.compile("-?\\d+(,\\d+)*?\\.?\\d+?"); List numbers = new ArrayList(); 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]

Usando Java 8, puedes 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 no tiene números negativos, puede deshacerse de replaceAll (y usar !s.isEmpty() en el filter ), ya que eso es solo para dividir correctamente algo así como 2-34 (esto también puede manejarse solo con expresiones regulares en split , pero es bastante complicado).

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

filter se deshace de las cadenas vacías iniciales y finales, así como de cualquier otra - eso no es parte de un número.

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


Alternativamente, Java 9 tiene un método Matcher.results , que debería permitir algo 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] 

Tal como están las cosas, ninguna de estas es una gran mejora en comparación con 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 streams.

Sugeriría que verifique los valores ASCII para extraer números de una cadena. Supongamos que tiene una cadena de entrada como myname12345 y si solo quiere extraer los números 12345 , puede hacerlo primero convirtiendo la cadena en matriz de caracteres y luego use el siguiente código psuedo.

 for(int i=0;i=48&&a[i]< =58) System.out.print(a[i]); } 

una vez que se extraen los números, añádalos a una matriz

Espero que esto ayude

Encontré esta expresión más simple

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