online - regex java 8
Grupos de captura de Java Regex (4)
Del doc:
Capturing groups</a> are indexed from left
* to right, starting at one. Group zero denotes the entire pattern, so
* the expression m.group(0) is equivalent to m.group().
Así que captura el grupo 0 envía toda la línea.
Estoy tratando de entender este bloque de código. En el primero, ¿qué es lo que estamos buscando en la expresión?
Según entiendo, se trata de cualquier carácter (0 o más veces *) seguido de cualquier número entre 0 y 9 (una o más veces +) seguido de cualquier carácter (0 o más veces *).
Cuando esto se ejecuta, el resultado es:
Found value: This order was placed for QT3000! OK?
Found value: This order was placed for QT300
Found value: 0
¿Alguien podría pasar por esto conmigo?
¿Cuál es la ventaja de usar grupos de captura?
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexTut3 {
public static void main(String args[]) {
String line = "This order was placed for QT3000! OK?";
String pattern = "(.*)(//d+)(.*)";
// Create a Pattern object
Pattern r = Pattern.compile(pattern);
// Now create matcher object.
Matcher m = r.matcher(line);
if (m.find()) {
System.out.println("Found value: " + m.group(0));
System.out.println("Found value: " + m.group(1));
System.out.println("Found value: " + m.group(2));
} else {
System.out.println("NO MATCH");
}
}
}
El problema que estás teniendo es con el tipo de cuantificador. Está utilizando un cuantificador codicioso en su primer grupo (índice 1 - el índice 0 representa todo el Pattern
), lo que significa que coincidirá tanto como le sea posible (y dado que es cualquier personaje, coincidirá con tantos caracteres como haya) son para cumplir la condición para los siguientes grupos).
En resumen, su primer grupo .*
Coincide con cualquier cosa siempre que el siguiente grupo //d+
pueda coincidir con algo (en este caso, el último dígito).
Según el tercer grupo, coincidirá con cualquier cosa después del último dígito.
Si lo cambia a un cuantificador reacio en su primer grupo, obtendrá el resultado que supongo que está esperando, es decir, la parte de 3000 .
Tenga en cuenta el signo de interrogación en el primer grupo.
String line = "This order was placed for QT3000! OK?";
Pattern pattern = Pattern.compile("(.*?)(//d+)(.*)");
Matcher matcher = pattern.matcher(line);
while (matcher.find()) {
System.out.println("group 1: " + matcher.group(1));
System.out.println("group 2: " + matcher.group(2));
System.out.println("group 3: " + matcher.group(3));
}
Salida:
group 1: This order was placed for QT
group 2: 3000
group 3: ! OK?
Más información sobre el Pattern
Java here .
Finalmente, los grupos de captura están delimitados por corchetes, y proporcionan una forma muy útil de utilizar referencias retrospectivas (entre otras cosas), una vez que su Pattern
coincide con la entrada.
En Java 6 los grupos solo pueden ser referenciados por su orden (cuidado con los grupos anidados y la sutileza de los pedidos).
En Java 7 es mucho más fácil, ya que puedes usar grupos con nombre.
Esto está totalmente bien.
- El primer grupo (
m.group(0)
) siempre captura toda el área que está cubierta por su expresión regular . En este caso, es toda la cadena. - Las expresiones regulares son codiciosas por defecto, lo que significa que el primer grupo captura tanto como sea posible sin violar la expresión regular. El
(.*)(//d+)
(la primera parte de su expresión regular) cubre el...QT300
int en el primer grupo y el0
en el segundo. - Puede solucionarlo rápidamente haciendo que el primer grupo no sea codicioso: cambie
(.*)
(.*?)
.
Para obtener más información sobre avaro vs perezoso, visite este sitio.
Su comprensión es correcta. Sin embargo, si revisamos:
-
(.*)
tragará toda la cadena; - necesitará devolver caracteres para que
(//d+)
esté satistificado (por lo que se captura0
y no3000
); - el último
(.*)
capturará el resto.
Sin embargo, no estoy seguro de cuál era la intención original del autor.