Usar expresiones regulares para extraer un valor en Java
Tengo varias cadenas en forma aproximada:
[some text] [some number] [some more text]
Quiero extraer el texto en [algún número] usando las clases de expresiones regulares de Java.
Sé aproximadamente qué expresión regular quiero usar (aunque todas las sugerencias son bienvenidas). Lo que realmente me interesa son las llamadas de Java para tomar la cadena de expresiones regulares y usarla en los datos de origen para producir el valor de [algún número].
Debo agregar que solo me interesa un solo [algún número] (básicamente, la primera instancia). Las cadenas de origen son cortas y no buscaré múltiples apariciones de [algún número].
Ejemplo completo:
private static final Pattern p = Pattern.compile("^([a-zA-Z]+)([0-9]+)(.*)");
public static void main(String[] args) {
// create matcher for pattern p and given string
Matcher m = p.matcher("Testing123Testing");
// if an occurrence if a pattern was found in a given string...
if (m.find()) {
// ...then you can use group() methods.
System.out.println(m.group(0)); // whole matched expression
System.out.println(m.group(1)); // first expression from round brackets (Testing)
System.out.println(m.group(2)); // second one (123)
System.out.println(m.group(3)); // third one (Testing)
}
}
Ya que estás buscando el primer número, puedes usar esta expresión regular:
^\D+(\d+).*
y m.group(1)
te devolverá el primer número. Tenga en cuenta que los números con signo pueden contener un signo menos:
^\D+(-?\d+).*
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Regex1 {
public static void main(String[]args) {
Pattern p = Pattern.compile("\\d+");
Matcher m = p.matcher("hello1234goodboy789very2345");
while(m.find()) {
System.out.println(m.group());
}
}
}
Producción:
1234
789
2345
Allain básicamente tiene el código java, así que puedes usarlo. Sin embargo, su expresión sólo coincide si sus números sólo están precedidos por una serie de caracteres de palabras.
"(\\d+)"
Debería poder encontrar la primera cadena de dígitos. No es necesario especificar lo que hay antes, si está seguro de que será la primera cadena de dígitos. Del mismo modo, no sirve de nada especificar qué hay después, a menos que así lo desee. Si solo desea el número y está seguro de que será la primera cadena de uno o más dígitos, entonces eso es todo lo que necesita.
Si espera que esté compensado por espacios, será aún más distintivo especificar
"\\s+(\\d+)\\s+"
podría ser mejor.
Si necesita las tres partes, esto servirá:
"(\\D+)(\\d+)(.*)"
EDITAR Las expresiones dadas por Allain y Jack sugieren que es necesario especificar algún subconjunto de elementos que no sean dígitos para poder capturar dígitos . Si le dice al motor de expresiones regulares que está buscando \d
, ignorará todo lo que esté antes de los dígitos. Si la expresión de J o A se ajusta a su patrón, entonces toda la coincidencia es igual a la cadena de entrada . Y no hay razón para especificarlo. Probablemente ralentice una partida limpia, si no se ignora por completo.
Además de Pattern , la clase Java String también tiene varios métodos que pueden trabajar con expresiones regulares, en tu caso el código será:
"ab123abc".replaceFirst("\\D*(\\d*).*", "$1")
donde \\D
es un carácter que no es un dígito.
En Java 1.4 y superior:
String input = "...";
Matcher matcher = Pattern.compile("[^0-9]+([0-9]+)[^0-9]+").matcher(input);
if (matcher.find()) {
String someNumberStr = matcher.group(1);
// if you need this to be an int:
int someNumberInt = Integer.parseInt(someNumberStr);
}