5

La encontré, y me dio la duda de qué significa esto:

var a = str.match(/\d+\.\d+|\d+\b|\d+(?=\w)/);

Lo que entiendo:

  • Match devolverá la coincidencia de la expresión regular

  • \d significa [0-9]

  • El + no entiendo que significa muy bien creo que sería como hacer {1,} (repetir 1 veces o más), pero realmente no entiendo muy bien como funciona.
  • \b es principio o fin de la palabra, pero no entiendo como funciona correctamente
  • ?= Ni idea
  • \w es cualquier alfanumérico a-zA-Z0-9_

Entonces resumiendo de todo esto, según lo que entiendo del patrón es:

Se buscara cualquier dígito que se pueda repetir 1 o más veces y después puede venir cualquier cosa . <- (metacaracter) , y después otro dígito cualquiera que puede repetirse O un dígito que puede repetirse 1 o mas veces al final de la string O un dígito y no entiendo que más hace después.

Por favor corríjanme. Intento aprender el maravilloso mundo de las expresiones regulares.

Mariano
  • 23,777
  • 20
  • 70
  • 102
Eduardo Sebastian
  • 4,908
  • 7
  • 30
  • 70
  • 2
    La verdad, este regex no tiene mucho sentido. Hasta es un poco contradictorio en su lógica. Yo no lo usaría. – Mariano Oct 05 '17 at 01:26
  • 1
    La expresion /d+\b/ implica que se busque un numero entero al final de una cadena de caracteres de palabra. – Migueledo Jul 06 '18 at 01:38

1 Answers1

6

Nota: Esta respuesta apunta a explicar los conceptos de la expresión regular, pero no recomiendo utilizar el patrón de esta pregunta. No tiene mucho sentido, y hasta es algo contradictorio en cómo está escrito.


Conceptos a tener en cuenta

Una barra antes de un metacaracter hace que pierda su significado especial. Una barra sirve para escapar a un caracter especial. Si bien un punto (.) coincide con cualquier caracter excepto saltos de línea, si queremos hacer que coincida con un punto literal, lo escapamos precediéndolo con una barra. Los metacaracteres (o caracteres especiales) son exclusivamente:

\   ^   $   .   |   ?   *   +   (   )   [   {

Y cuando se quiere hacer coincidir con el caracter literal, se usa una \.
Así, \. coincide con ".".


El + es un cuantificador. Y como todo cuantificador, sirve para repetir la estructura anterior. El + repite la estructura anterior 1 o más veces. Los cuantificadores en expresiones regulares son:

  Cuant.   Descripción                             
 -------- ------------------------------------------------------------------ 
  ?        1 o 0                                                             
  ??       0 o 1                                                             
  *        infinito a 0                                                      
  *?       0 a infinito                                                      
  +        infinito a 1                                                      
  +?       1 a infinito                                                      
  {n}      exactamente n repeticiones                                      
  {m,n}    hasta n repeticiones, mínimo m                         
  {m,n}?   mínimo m, hasta n repeticiones
  {m,}     entre m e infinitas repeticiones, cuantos más puedan coincidir    
  {m,}?    entre m e infinitas repeticiones, cuantas menos puedan coincidir
  {,n}     entre 0 y n repeticiones (sólo Python y Ruby)

Ejemplos:

  Cuant.    Descripción                             
 --------- --------------------------------------------------------------------
  \w+       1 o más alfanuméricos (incluye "_"), cuantos más puedan coincidir
  ¡(ja){3}! coincide con el texto "¡jajaja!"
  x{3,6}    3 a 6 letras "x" consecutivas, cuantas más puedan coincidir
  @{2,5}?   2 a 5 arrobas consecutivas, cuantas menos puedan coincidir

En tu expresión, \d+\.\d+ coincide con un número con decimales, por ejemplo: 1234.5, 21.0, 5.43210, etc. Es 1 o más dígitos (\d+), seguido de un punto (\.), seguido de 1 o más dígitos (\d+).


\b es un límite de palabra completa. Es una aserción y, como tal, no coincide con un caracter sino con una posición. Se llama límite de palabra completa porque coincide en una posición donde a un lado tenga un caracter de palabra (\w, que es lo mismo que [a-zA-Z0-9_]) y al otro lado no tenga un caracter de palabra (\W -que en mayúscula es lo opuesto-, o el inicio o fin del texto).

Técnicamente, \b concide en el medio de estos 4 casos: \w\W, \W\w, ^\w o \w$. En la práctica, nos permite que una expresión como /\bola\b/ coincida con un "una ola gigante" o con ¡surfeamos esa ola!" y al mismo tiempo que no coincida con "hola Manola, ¿estás sola?".
-Dejo otras palabras para la imaginación del lector :)


(?=patrón) es una inspección positiva (o positive lookahead). En castellano, significa que "está seguido por". Una inspección positiva (?=...) intenta una coincidencia con el patrón de la misma y, si coincide, vuelve a la posición en la que se encontraba antes de intentarlo. Es decir, no consume caracteres. Obviamente si no coincide, falla el intento actual.

Como no consume caracteres, coincide con la posición, y no con los caracteres en sí. En tu regex, \d+(?=\w) coincide con dígitos que estén seguidos por un caracter de palabra, pero no incluye a ese caracter dentro del resultado.



Explicación de /\d+\.\d+|\d+\b|\d+(?=\w)/

Son 3 alternativas:

  1. \d+\.\d+ - Un número con decimales.
  2. \d+\b - Un entero que no está seguido por un caracter de palabra.
  3. \d+(?=\w) - Un entero que está seguido por un caracter de palabra.

Aparentemente, está intentando coincidir con números con o sin decimales. Sin embargo, quien la haya escrito se hizo algún lío. Es algo incoherente cómo está escrita. ¿Para qué las alternativas 2 y 3 al mismo tiempo? Ni idea.

Es bastante más sencillo y coherente utilizar esta expresión para un número con o sin decimales:

/\d+(?:\.\d+)?/
  • \d+ - 1 o más dígitos.
  • (?:\.\d+)? Es un grupo. (?:...) se diferencia de un paréntesis normal en que no utiliza memoria extra para capturar lo que haya coincidido con los paréntesis. El ? al final hace que todo el grupo sea opcional. Así, \.\d+ coincide con la parte decimal, sólo si existe.
Mariano
  • 23,777
  • 20
  • 70
  • 102
  • Siempre voy a admirar la manera tan elegante que tienes de explicar sobre RegEx. Un abrazo hermano :D – fredyfx Oct 06 '17 at 22:17
  • 3
    Gracias @fredyfx! Todo un halago viniendo del maestro de los maestros de .Net... Ya volveré a andar por estos pagos más frecuentemente. – Mariano Oct 06 '17 at 22:28
  • de nada hermano :D gracias por el halago aunque no es para tanto, sigo siendo estudiante, hay mucho por aprender :) – fredyfx Oct 06 '17 at 22:45