Diferente comportamiento de la misma expresión regular en Python y Java.

En primer lugar, mis disculpas ya que no conozco expresiones regulares tan bien.

Estoy usando una expresión regular para hacer coincidir una cadena. Lo probé en la interfaz de línea de comandos de Python, pero cuando lo ejecuté en Java, produjo un resultado diferente.

Ejecución de Python:

re.search("[0-9]*[\\.[0-9]+]?[^0-9]*D\\([M|W]\\)\\s*US", "9.5 D(M) US"); 

da el resultado como:

  

Pero el código de Java

 import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; class RegexTest { private static final Pattern FALLBACK_MEN_SIZE_PATTERN = Pattern.compile("[0-9]*[\\.[0-9]+]?[^0-9]*D\\([M|W]\\)\\s*US"); public static void main(String[] args) { String strTest = "9.5 D(M) US"; Matcher matcher = FALLBACK_MEN_SIZE_PATTERN.matcher(strTest); if (matcher.find()) { System.out.println(matcher.group(0)); } } } 

da la salida como:

5 D (M) US

No entiendo por qué se está comportando de manera diferente.

Aquí está el patrón que funcionará igual en Java y Python:

 "[0-9]*(?:\\.[0-9]+)?[^0-9]*D\\([MW]\\)\\s*US" 

Ver demos de Python y Java .

En Python, [\\.[0-9]+]? se lee como 2 subpatrones: [\.[0-9]+ (1 o más . s, [ s, o dígitos) y ]? (0 o 1 ] ). Vea cómo funciona su expresión regular en Python aquí . O, con más detalle con grupos de captura, aquí .

En Java, se lee como una clase de un solo carácter (es decir, [ y ] dentro se ignoran ya que el motor de expresiones regulares no puede analizarlos correctamente, por lo que todo el subpatrón representa 0 o 1, un dígito o + ) y dado que es opcional, no estaba capturando nada (puede obtener una sugerencia visual en Visual Regex Tester , escriba 123.+[] como entrada y [\.[0-9]+]? como regex).

Y un toque final: [M|W] significa M , | , o W , aunque creo que quiso decir [MW] = M o W

No soy un experto en Python, así que no puedo decirte por qué funcionó en Python, pero en Java, tu problema es el [\\.[0-9]+]? parte. Probablemente quiso que fuera (\\.[0-9]+)? .

Tal como está, es una lista de caracteres dentro de un [] seguido de un ? . Es decir, esta parte de la expresión solo coincide con un solo carácter o cero, por lo que no puede coincidir con .5 juntos.

Aquí hay una ilustración de los bashs coincidentes:

Demostración gráfica de emparejamiento en Java.

Ahora, si su patrón usa () lugar de [] , este sería el resultado:

introduzca la descripción de la imagen aquí