ES2018 Parte 1: Mejoras a RegExp

JavaScript sigue evolucionando como lenguaje y ya se ha definido que características se van a añadir este año, veamos en detalle cada una.

“A woman holding up a clipboard with a calendar in front of her chest” by Brooke Lark on Unsplash
Nota: Este contenido lo publiqué primero en mi newsletter, la semana después de publicar el newsletter publico en mi blog, si quieres ser el primero en leer suscríbete.

En Enero el TC39 se reunió y se decidió las propuestas que llegarán a stage 4 y por consiguiente serán incluidas dentro de ECMAScript 2018.

Para poder cubrir en detalle cada nueva característica, vamos a dividirlo en una sería de posts, donde este será el primero

Parte1: Mejoras a RegExp

Parte2: Rest/Spread Object y Promise.finally

Parte3: Iteración asincrona

Sí estas interesado en cuales son todas las propuestas actuales y sus estados puedes verlas acá

Hoy vamos a hablar de las mejoras incluidas a las expresiones regulares

Capturar por grupos (named capture groups)

Actualmente podemos capturar una regexp (expresión regular) en grupos y el resultado es un array, por ejemplo si queremos capturar un número separado por espacios

//live: https://regex101.com/r/fUSehr/1
const pattern = /(\d{3}).(\d{3}).(\d{4})/u
const number = pattern.exec('320 123 2312')
console.log(number) // [ "320 123 2312", "320", "123", "2312"]

Esto es bastante útil pero no lo suficientemente claro o legible, por eso en ES2018, podemos identificarlos con un nombre a cada grupo por ejemplo (?<numero>\d)

\\ live: https://regex101.com/r/HPBqyI/3
const pattern = /(?<indicator>\d{3}).(?<first>\d{3}).(?<second>\d{4})/u;
const number = pattern.exec('320 301 1239');
console.log(result.groups) \\ {indicator: '320', first: '301', second: '1239'}

Cómo vemos ahora vamos a tener un objeto donde los keys van a ser iguales a los nombres que le asignemos a los grupos.

También puedes usar destructuring 😉

const {groups: { indicador, first, second}} = pattern.exec('320 301 1239');

Afirmaciones hacia atrás (Lookbehind Assertions)

Con Regex podemos tener un patrón que se daba cumplir pero no este en el resultado al evaluarlo, actualmente podemos evaluar que se cumpla este patrón delante de lo que evaluamos, por ejemplo

// live: https://regex101.com/r/Wwp5lr/1
const pattern = /\d+(?= pesos)/g 
console.log(pattern.exec('12 pesos')) // ["12"]
console.log(pattern.exec('12')) // null
// La palabra pesos debe estar delante, pero no aparece en el resultado

En ES2018 se a agregado esta funcionalidad pero buscando antes, usando la sintaxis (?<=\ )esto quiere decir que podemos hacer lo siguiente

// live: https://regex101.com/r/GxmMqt/1
const pattern = /(?<=\$)\d+/g
console.log(pattern.exec('$12')) // ["12"]
console.log(pattern.exec('12')) // null
// El patrón debe estar atrás para que se evalue correcto

También podemos evaluar que no sea precedido por un patrón

// live: https://regex101.com/r/OaAjM7/2
const pattern = /(?<!\€)\d+/g
console.log(pattern.exec('$12')) // ["12"]

Flag s(dotAll)

En expresiones regulares el . va a hacer mach con cualquier carácter, pero sin incluir las terminaciones de linea como \n , para esto en ES2018 tenemos el nuevo flag s que nos permite cubrir este caso.

/Esta.Casa/u.test('Esta\nCasa'); // false
/Esta.Casa/su.test('Esta\nCasa'); // true

Escape de propiedades unicode (Unicode Property Escapes)

El estándar unicode asigna varias propiedades a cada símbolo, desde ES2018 vamos a poder acceder a estas propiedades dentro de las expresiones regulares, esto va a ser solo posible usando el flag u

La sintaxis es /p{Scrip_name} por ejemplo si quieres buscar los símbolos que sea de números puedes usar \p{Decimal_Number}

Así con cualquier propiedad de unicode, está característica me parece increíble por lo legible que hace las expresiones regulares

Palabras finales

Recuerda después de los cambios incluidos en ES6 que fueron bastantes, cada año solo van a incluirse en el lenguaje unos pocos. Así que no te asuste o te sientas abrumado, tienes todo un año para aprender unas cuantas cosas nuevas. 😛

Si quieres usar una propuesta que aún no ha sido incluida oficialmente en el lenguaje puedes usar babel.

La próxima hablamos sobre Spread/Rest Object y Promise.finally