Escapado de caracteres especiales en expresiones regulares de PHP

Supongamos que queremos hacer que un carácter especial se represente a sí mismo. Para ello debemos escaparlo usando la barra invertida. Veamos algunos ejemplos.

Ejemplo

En el siguiente ejemplo, el autor de la expresión regular quería que el patrón de búsqueda fuera: letra 'a', luego signo más '+', luego letra 'x'. Sin embargo, el autor del código no escapó el carácter '+' y por lo tanto el patrón de búsqueda en realidad es: letra 'a' una o más veces, luego letra 'x':

php<?php
  $str = 'a+x ax aax aaax';
  $res = preg_replace('#a+x#', '!', $str);
?>

Como resultado, en la variable se almacenará lo siguiente:

php'a+x ! ! !'

Ejemplo

Y ahora el autor escapó el signo más con la barra invertida. Ahora el patrón de búsqueda es como debería ser: letra 'a', luego signo más '+', luego letra 'x'.

php<?php
  $str = 'a+x ax aax aaax';
  $res = preg_replace('#a\+x#', '!', $str);
?>

Como resultado, en la variable se almacenará lo siguiente:

php'! ax aax aaax'

Ejemplo

En este ejemplo el patrón es: letra 'a', luego punto '.', luego letra 'x':

php<?php
  $str = 'a.x abx azx';
  $res = preg_replace('#a\.x#', '!', $str);
?>

Como resultado, en la variable se almacenará lo siguiente:

php'! abx azx'

Ejemplo

En el siguiente ejemplo el autor olvidó escapar la barra y bajo la expresión regular cayeron todas las subcadenas, ya que el punto sin escapar representa cualquier carácter:

php<?php
  $str = 'a.x abx azx';
  $res = preg_replace('#a.x#', '!', $str);
?>

Como resultado, en la variable se almacenará lo siguiente:

php'! ! !'

Ejemplo

Preste atención a que si olvida la barra invertida para el punto (cuando debería representarse a sí mismo) - esto puede pasar inadvertido:

php<?php
  preg_replace('#a.x#', '!', 'a.x'); // devolverá '!', como queríamos
?>

Visualmente funciona correctamente (ya que el punto representa cualquier carácter, incluyendo el punto normal '.'). Pero si cambiamos la cadena en la que se realizan los reemplazos - veremos nuestro error:

php<?php
  preg_replace('#a.x#', '!', 'a.x abx azx'); // devolverá '! ! !', pero se esperaba '! abx azx'
?>