¿Cuál es la importancia del Pattern.compile()
método?
¿Por qué necesito compilar la cadena de expresiones regulares antes de obtener el Matcher
objeto?
Por ejemplo :
String regex = "((\\S+)\\s*some\\s*";
Pattern pattern = Pattern.compile(regex); // why do I need to compile
Matcher matcher = pattern.matcher(text);
new Pattern(regex)
lugar de una función de compilación estática. El comentario de Marcolopes está sobre el terreno.Respuestas:
El
compile()
método siempre se llama en algún momento; es la única forma de crear un objeto Patrón. Entonces la pregunta es realmente, ¿por qué debería llamarlo explícitamente ? Una razón es que necesita una referencia al objeto Matcher para poder usar sus métodos, comogroup(int)
recuperar el contenido de los grupos de captura. La única forma de obtener el objeto Matcher es a través delmatcher()
método del objeto Pattern , y la única forma de obtener el objeto Pattern es a través delcompile()
método. Luego está elfind()
método que, a diferenciamatches()
, no está duplicado en las clases String o Pattern.La otra razón es evitar crear el mismo objeto Patrón una y otra vez. Cada vez que utiliza uno de los métodos basados en expresiones regulares en String (o el
matches()
método estático en Pattern), crea un nuevo Pattern y un nuevo Matcher. Entonces este fragmento de código:... es exactamente equivalente a esto:
Obviamente, eso está haciendo mucho trabajo innecesario. De hecho, puede llevar más tiempo compilar la expresión regular y crear una instancia del objeto Pattern que realizar una coincidencia real. Entonces, por lo general, tiene sentido sacar ese paso del círculo. También puede crear el Matcher con anticipación, aunque no son tan caros:
Si está familiarizado con las expresiones regulares de .NET, puede que se pregunte si el
compile()
método de Java está relacionado con elRegexOptions.Compiled
modificador de .NET ; la respuesta es no. ElPattern.compile()
método de Java es simplemente equivalente al constructor Regex de .NET. Cuando especifica laCompiled
opción:... compila la expresión regular directamente en el código de bytes CIL, lo que le permite funcionar mucho más rápido, pero a un costo significativo en el procesamiento inicial y el uso de memoria; considérelo como esteroides para expresiones regulares. Java no tiene equivalente; no hay diferencia entre un patrón creado detrás de escena
String#matches(String)
y uno con el que crea explícitamentePattern#compile(String)
.(EDITAR: originalmente dije que todos los objetos .NET Regex se almacenan en caché, lo cual es incorrecto. Desde .NET 2.0, el almacenamiento en caché automático ocurre solo con métodos estáticos como
Regex.Matches()
, no cuando se llama a un constructor Regex directamente. Ref )fuente
reset
utilizar un objeto Matcher que solo sea utilizado por un hilo a la vez para reducir las asignaciones.Compile analiza la expresión regular y crea una representación en memoria . La sobrecarga para compilar es significativa en comparación con una coincidencia. Si utiliza un patrón repetidamente , obtendrá algo de rendimiento para almacenar en caché el patrón compilado.
fuente
Cuando compila,
Pattern
Java realiza algunos cálculos para que la búsqueda de coincidencias enString
s sea más rápida. (Crea una representación en memoria de la expresión regular)Si va a reutilizar
Pattern
varias veces, verá un gran aumento de rendimiento en comparación con la creación de una nuevaPattern
cada vez.En el caso de usar el Patrón solo una vez, el paso de compilación parece una línea extra de código, pero, de hecho, puede ser muy útil en el caso general.
fuente
Matcher matched = Pattern.compile(regex).matcher(text);
. Esto tiene ventajas sobre la introducción de un solo método: los argumentos se nombran de manera efectiva y es obvio cómo factorizarlosPattern
para un mejor rendimiento (o dividirlos entre métodos).Es cuestión de rendimiento y uso de memoria, compile y mantenga el patrón cumplido si necesita usarlo mucho. Un uso típico de expresiones regulares es validar la entrada del usuario (formato) y también formatear los datos de salida para los usuarios , en estas clases, guardar el patrón cumplido parece bastante lógico, ya que generalmente se llama mucho.
A continuación se muestra un validador de muestra, que realmente se llama mucho :)
Como lo mencionó @Alan Moore, si tiene expresiones regulares reutilizables en su código (antes de un bucle, por ejemplo), debe compilar y guardar el patrón para su reutilización.
fuente
Pattern.compile()
permitir reutilizar una expresión regular varias veces (es seguro para subprocesos). El beneficio de rendimiento puede ser bastante significativo.Hice un punto de referencia rápido:
compileOnce fue entre 3 y 4 veces más rápido . Supongo que depende en gran medida de la expresión regular en sí, pero para una expresión regular que se usa a menudo, opto por una
static Pattern pattern = Pattern.compile(...)
fuente
La compilación previa de la expresión regular aumenta la velocidad. Reutilizar el Matcher te da otra ligera aceleración. Si el método se llama con frecuencia, digamos que se llama dentro de un ciclo, el rendimiento general ciertamente aumentará.
fuente
Similar a 'Pattern.compile', hay 'RECompiler.compile' [de com.sun.org.apache.regexp.internal] donde:
1. el código compilado para el patrón [az] tiene 'az'
2. código compilado para el patrón [0-9] tiene '09' en él
3. El código compilado para el patrón [abc] tiene 'aabbcc' en él.
Por lo tanto, el código compilado es una excelente manera de generalizar varios casos. Por lo tanto, en lugar de tener diferentes situaciones de manejo de código 1, 2 y 3. El problema se reduce a comparar con el ascii del elemento presente y siguiente en el código compilado, de ahí los pares. Así
a. cualquier cosa con ascii entre a y z está entre a y z
b. cualquier cosa con ascii entre 'ay a es definitivamente' a '
fuente
La clase de patrón es el punto de entrada del motor de expresiones regulares. Puede usarlo a través de Pattern.matches () y Pattern.comiple (). # Diferencia entre estos dos. Match () : para comprobar rápidamente si un texto (String) coincide con una expresión regular determinada. comiple () : crea la referencia de Pattern. Por lo tanto, puede usar varias veces para hacer coincidir la expresión regular con varios textos.
Para referencia:
fuente