<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Rafa Moral</title>
    <description>The latest articles on DEV Community by Rafa Moral (@rmoralp).</description>
    <link>https://dev.to/rmoralp</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F256335%2Fe1ff8f12-2724-449d-acb9-90bf79ab7b40.jpeg</url>
      <title>DEV Community: Rafa Moral</title>
      <link>https://dev.to/rmoralp</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rmoralp"/>
    <language>en</language>
    <item>
      <title>Next.js multi idioma</title>
      <dc:creator>Rafa Moral</dc:creator>
      <pubDate>Tue, 24 Nov 2020 21:12:17 +0000</pubDate>
      <link>https://dev.to/rmoralp/next-js-multi-idioma-4mc3</link>
      <guid>https://dev.to/rmoralp/next-js-multi-idioma-4mc3</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Con la versión 10 de Next.js han introducido el soporte a internacionalización. Se puede configurar un listado de idiomas, el idioma por defecto y, en caso de requerirlo, un dominio específico para cada uno. Next.js hará la detección del idioma del usuario y gestionará las rutas automáticamente.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;La gestión de idioma por Next.js debe ser complementada con la gestión de las traducciones, utilizando alguna biblioteca Open Source existente o llevando a cabo el desarrollo nosotros mismos. En la documentación de Next.js recomiendan soluciones como &lt;code&gt;react-intl&lt;/code&gt;, &lt;code&gt;react-i18next&lt;/code&gt;, &lt;code&gt;lingui&lt;/code&gt; o &lt;code&gt;rosetta&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;En este artículo, os voy a explicar cómo he llevado a cabo la implementación de &lt;a href="https://github.com/airbnb/polyglot.js"&gt;Polyglot.js&lt;/a&gt;, una herramienta desarrollada y mantenida por Airbnb.&lt;/p&gt;

&lt;p&gt;Lo primero que deberemos hacer es instalar la dependencia:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm install node-polyglot --S
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Internacionalización de rutas con Next.js 10 o superior
&lt;/h2&gt;

&lt;p&gt;La configuración de internacionalización en Next.js debe hacerse en el archivo &lt;code&gt;next.config.js&lt;/code&gt;, en este ejemplo vamos a utilizar la opción de &lt;em&gt;Sub-path Routing&lt;/em&gt; con locales sin región, es decir, las url's de las páginas de cada idioma tendrán &lt;code&gt;/es&lt;/code&gt; o &lt;code&gt;/en&lt;/code&gt; al inicio del &lt;em&gt;path&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;A continuación la configuración de &lt;code&gt;next.config.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// next.config.js&lt;/span&gt;
&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;i18n&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cm"&gt;/* Listado de locales que vamos a soportar */&lt;/span&gt;
    &lt;span class="na"&gt;locales&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;es&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="cm"&gt;/* Locale seleccionado por defecto */&lt;/span&gt;
    &lt;span class="na"&gt;defaultLocale&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;es&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Traducción de textos con Polyglot.js en Next.js
&lt;/h2&gt;

&lt;p&gt;Para integrar Polyglot.js con Next.js he creado un contexto, el cual recibirá el &lt;code&gt;locale&lt;/code&gt; actual en el que está corriendo la aplicación. Este contexto contendrá la instancia de Polyglot con la configuración seleccionada.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/I18n.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;createContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useMemo&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Polyglot&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;node-polyglot&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;// Creamos las traducciones para cada idioma.&lt;/span&gt;
&lt;span class="c1"&gt;// Es recomendable mover esto a otros archivos.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;literals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;en&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;es&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hola&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Definimos los idiomas a los que damos soporte&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;locales&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;en&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;es&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;es&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Creamos el contexto&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;I18nContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createContext&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Componente que encapsula la aplicación dentro del Provider.
 * Este componente será el responsable de actualizar el idioma activado en la aplicación
 */&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;I18n&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Cada vez que el locale cambie, obtendremos una instancia de i18n actualizada.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;i18n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useMemo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
      &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Polyglot&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="nx"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;phrases&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;literals&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;I18nContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Provider&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;i18n&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/I18nContext.Provider&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Creamos un Hook para utilizar el contexto en los componentes que necesitemos&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useTranslate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;useContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;I18nContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;locales&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useTranslate&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;I18n&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lo siguiente que debemos hacer consiste en utilizar este contexto en la aplicación. Yo he optado por utilizar el componente I18n directamente en el componente &lt;code&gt;_app.js&lt;/code&gt;, enviándole la &lt;em&gt;prop&lt;/em&gt; &lt;code&gt;locale&lt;/code&gt; que se puede obtener directamente del &lt;em&gt;Hook&lt;/em&gt; &lt;code&gt;useRouter&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/pages/_app.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;useRouter&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next/router&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;I18n&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../i18n&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;MyApp&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pageProps&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useRouter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;I18n&lt;/span&gt; &lt;span class="nx"&gt;locale&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;pageProps&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/I18n&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;MyApp&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Localización de textos en componentes y páginas
&lt;/h2&gt;

&lt;p&gt;Para utilizar las traducciones que hemos ido añadiendo en el objeto &lt;code&gt;literals&lt;/code&gt; utilizaremos el valor del contexto, que corresponde con la instancia de Polyglot. Para ello, utilizaremos el &lt;em&gt;Hook&lt;/em&gt; &lt;code&gt;useTranslate&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/pages/index.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;useTranslate&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../i18n&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Home&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;i18n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useTranslate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;i18n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Home&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>nextj</category>
      <category>react</category>
      <category>i18n</category>
      <category>polyglot</category>
    </item>
    <item>
      <title>Parte 1: RegExp - Qué son, para qué se utilizan y cómo funcionan</title>
      <dc:creator>Rafa Moral</dc:creator>
      <pubDate>Tue, 17 Nov 2020 18:42:02 +0000</pubDate>
      <link>https://dev.to/rmoralp/parte-1-regexp-que-son-para-que-se-utilizan-y-como-funcionan-2fne</link>
      <guid>https://dev.to/rmoralp/parte-1-regexp-que-son-para-que-se-utilizan-y-como-funcionan-2fne</guid>
      <description>&lt;p&gt;Las expresiones regulares suelen estar olvidadas por la gran mayoría de Frontend, imagino que algunos motivos pueden ser su complejidad y las pocas veces que se necesitan. Con esta serie de artículos pretendo otorgarles la importancia que merecen explicando todo lo que un Frontend debe conocer sobre ellas.&lt;/p&gt;

&lt;p&gt;En esta primera parte, pretendo explicar qué son, para qué se utilizan y cómo funcionan.&lt;/p&gt;

&lt;h2&gt;
  
  
  Qué son las expresiones regulares
&lt;/h2&gt;

&lt;p&gt;Se suele definir una expresión regular como:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Una expresión regular es una especificación declarativa que describe la estructura textual a la que debe corresponder una cadena de coincidencia&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;O, dentro del contexto de Google Analytics, también como:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Las expresiones regulares son secuencias específicas de caracteres que coinciden con patrones de sus datos de Analytics o con parte de estos.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sin embargo, &lt;strong&gt;las expresiones regulares no son declarativas, ni describen, ni especifican una estructura&lt;/strong&gt;. Tampoco son cadenas con las que deba coincidir nada.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Las expresiones regulares son código.&lt;/strong&gt; Al escribir una expresión regular escribimos un "programa", en un lenguaje un poco peculiar, pero al fin y al cabo estamos programando. Por lo tanto, ésta es una definición más concreta de lo que son las expresiones regulares:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Una expresión regular es una especificación imperativa de una secuencia de bloques de instrucciones estructuradas, diseñada para ejecutar alguna tarea en una máquina virtual altamente especializada. Las expresiones regulares son secuencias estructuradas de instrucciones, bucles, control de flujo, aserciones y gestión de excepciones.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Una expresión regular también es conocida por regex o RegExp.&lt;/p&gt;

&lt;h2&gt;
  
  
  Para qué se utilizan
&lt;/h2&gt;

&lt;p&gt;Utilizamos expresiones regulares para evitar tener que escribir código en Javascript (aunque también en C, C#, Perl, PHP, Python o el lenguaje que utilicemos).&lt;/p&gt;

&lt;p&gt;Utilizar una RegExp es el equivalente a llamar a una función, ya que a partir de un argumento -la cadena que debe coincidir- se ejecutan sus instrucciones (la regex) y recogemos el resultado, que puede ser un booleano o una serie de resultados como grupo de coincidencias.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dialectos
&lt;/h2&gt;

&lt;p&gt;Las regex no son un único lenguaje, son toda una familia de lenguajes o dialectos y cada uno de ellos tiene sus peculiaridades y suelen ser incompatibles entre sí. Todos utilizan las mismas instrucciones, con significados completamente distintos.&lt;/p&gt;

&lt;p&gt;Los dialectos más importantes son:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;BRE: PHP, ed, sed, grep.&lt;/li&gt;
&lt;li&gt;ERE: egrep, awk, Tcl&lt;/li&gt;
&lt;li&gt;EMACS: emacs&lt;/li&gt;
&lt;li&gt;VIM: vim&lt;/li&gt;
&lt;li&gt;PCRE: PHP, Perl, Javascript (parcialmente), apache, Google Analytics (un subconjunto muy reducido), C#, java, python...&lt;/li&gt;
&lt;li&gt;PSIX: Perl 6&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Por lo tanto, tenemos que determinar qué lenguaje habla nuestro entorno, que en este caso es &lt;strong&gt;PCRE para Javascript&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  El modelo de ejecución
&lt;/h2&gt;

&lt;p&gt;En el modelo de ejecución de una regex simple como puede ser &lt;code&gt;/abc/&lt;/code&gt;, vemos tres instrucciones:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;coincide con una &lt;code&gt;a&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;a continuación coincide con una &lt;code&gt;b&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;a continuación coincide con una &lt;code&gt;c&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;En cada instrucción hay una excepción implícita, coincide o lanza excepción, en ese caso, hace &lt;em&gt;backtrack&lt;/em&gt; y continúa con el siguiente carácter.&lt;/p&gt;

&lt;p&gt;Por lo tanto, podemos representar la regex &lt;code&gt;/abc/&lt;/code&gt; como si de una maquina de estados finita (&lt;strong&gt;FSM&lt;/strong&gt;) se tratase mediante el siguiente gráfico:&lt;/p&gt;

&lt;p&gt;&lt;a href="//res.cloudinary.com/rmoralp/image/upload/c_scale%2Cq_auto%2Cw_736%2Cf_auto/v1560098959/regex-modelo-ejecucion" class="article-body-image-wrapper"&gt;&lt;img src="//res.cloudinary.com/rmoralp/image/upload/c_scale%2Cq_auto%2Cw_736%2Cf_auto/v1560098959/regex-modelo-ejecucion" alt="Modelo de ejecución de una regex"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="//res.cloudinary.com/rmoralp/image/upload/c_scale%2Cq_auto%2Cw_736%2Cf_auto/v1560098959/regex-modelo-ejecucion-match" class="article-body-image-wrapper"&gt;&lt;img src="//res.cloudinary.com/rmoralp/image/upload/c_scale%2Cq_auto%2Cw_736%2Cf_auto/v1560098959/regex-modelo-ejecucion-match" alt="Modelo de ejecución de una regex haciendo match"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Ejemplo de ejecución
&lt;/h3&gt;

&lt;p&gt;Dada la cadena de texto &lt;code&gt;01ababc&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="//res.cloudinary.com/rmoralp/image/upload/c_scale%2Cq_auto%2Cw_715%2Cf_auto/v1560176565/ejemplo-de-ejecucio%CC%81n" class="article-body-image-wrapper"&gt;&lt;img src="//res.cloudinary.com/rmoralp/image/upload/c_scale%2Cq_auto%2Cw_715%2Cf_auto/v1560176565/ejemplo-de-ejecucio%CC%81n" alt="Ejemplo de ejecución de una regex"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;¡Y así es cómo funciona una expresión regular!&lt;/p&gt;

&lt;h2&gt;
  
  
  Las instrucciones
&lt;/h2&gt;

&lt;p&gt;Cada carácter en una regex es una instrucción y por norma general, o coincide con este carácter o hace &lt;em&gt;backtrack&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;Habitualmente tenemos que presentar a una regex una serie de alternativas u opciones, por ejemplo &lt;code&gt;/abc|abx/&lt;/code&gt;. En este caso, tenemos dos posibles caminos, &lt;strong&gt;coincide con una &lt;code&gt;a&lt;/code&gt;, una &lt;code&gt;b&lt;/code&gt; y una &lt;code&gt;c&lt;/code&gt; o con una &lt;code&gt;a&lt;/code&gt;, una &lt;code&gt;b&lt;/code&gt; y una &lt;code&gt;x&lt;/code&gt;.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Es muy importante conocer que toda RegExp:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prueba todos los caminos posibles empezando por la izquierda.&lt;/li&gt;
&lt;li&gt;Intenta hacer el mínimo &lt;em&gt;backtracking&lt;/em&gt; posible.&lt;/li&gt;
&lt;li&gt;Si hace match, termina.&lt;/li&gt;
&lt;li&gt;Si falla, reintenta con la siguiente posición.&lt;/li&gt;
&lt;li&gt;Si fallan todos los caminos, en cada reintento, reporta fallo.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Además, las RegExp no son muy listas... El motor intenta siempre todos los caminos posibles antes de avanzar por el texto y siempre encuentra el primero de los posibles substrings que coincide en vez de la mejor coincidencia, por lo que esto tiene algunas consecuencias.&lt;/p&gt;

&lt;p&gt;Ante este escenario:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cadena: "Siempre utilizo el mail de gmail"&lt;/li&gt;
&lt;li&gt;RegExp: &lt;code&gt;/gmail|mail/&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;El resultado es: "Siempre utilizo el &lt;strong&gt;mail&lt;/strong&gt; de gmail"&lt;/p&gt;

&lt;p&gt;Por lo que, &lt;strong&gt;una expresión regular siempre encuentra la primera y más corta coincidencia&lt;/strong&gt; y eso hace que sea muy fácil cometer errores de éste estilo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cadena: "He perdido la &lt;strong&gt;foto&lt;/strong&gt;grafía"&lt;/li&gt;
&lt;li&gt;RegExp: &lt;code&gt;/foto|fotografía/&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para evitarlo, invertid siempre el orden de las keywords en la regex.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cadena: "He perdido la &lt;strong&gt;fotografía&lt;/strong&gt;"&lt;/li&gt;
&lt;li&gt;RegExp: &lt;code&gt;/fotografía|foto/&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;&lt;strong&gt;⚠️ Las expresiones regulares que fallan suelen ser mucho más lentas que las que coinciden. Y recordad algo muy importante, las expresiones regulares tienen la manía de hacer lo que les decimos que hagan, no lo que queremos que hagan.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>regex</category>
      <category>regularexpressions</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
