Probar expresiones regulares online: elegir el motor, probar bien y llevarlas a JavaScript, Python o Java
Un probador de expresiones regulares muestra, mientras escribes, qué coincide en un texto de ejemplo, qué capturó cada grupo y dónde falló el patrón. Es la forma más rápida de escribir una regex. También es donde empiezan muchos errores, porque el probador usa otro motor, otros flags u otro string que tu programa. Con un poco de disciplina, lo que ves en el probador es lo que obtendrás en producción.
Elige el motor que usa tu código
No existe un único lenguaje de expresiones regulares. JavaScript, Python, PCRE (PHP y muchas herramientas), Java, .NET y RE2 de Go comparten lo básico y se diferencian en funciones que importan.
función JavaScript Python PCRE/PHP Java .NET Go (RE2)
grupo con nombre (?<n>..) (?P<n>..) (?<n>..) (?<n>..) (?<n>..) (?P<n>..)*
lookbehind sí ancho fijo ancho fijo acotado cualquiera no
posesivo a++ no 3.11+ sí sí no no
atómico (?>..) no 3.11+ sí sí sí no
referencias \1 sí sí sí sí sí no
fin del string $ (sin m) \Z \z o $ + D \z \z \z
* Go 1.22+ acepta también (?<n>...); Python solo acepta (?P<n>...)
RE2 de Go no tiene lookaround ni referencias hacia atrás, a propósito, porque garantiza tiempo lineal. Un patrón que funciona en un probador de JavaScript puede no compilar en Go. Selecciona el motor correcto en el probador antes de empezar, no al final.
Usa los mismos flags
Los flags cambian el resultado tanto como el patrón: g (todas las coincidencias), i (sin distinguir mayúsculas), m (^ y $ por línea), s (el punto incluye saltos de línea), u/v (Unicode) y x (modo extendido en PCRE y Python). Muchos probadores activan g y m por defecto, porque resaltar todas las coincidencias en todas las líneas queda bien. Un patrón de validación que parece correcto con m activo acepta válido\ncualquier cosa en un código donde se comprueba el string completo.
Configura el probador con exactamente los flags de tu código, incluido ninguno.
Prueba con una lista de casos, no con un solo ejemplo
Una línea de ejemplo demuestra poco. Pega dos listas: textos que deben coincidir y textos que no. Para un patrón de número de pedido como ^PED-\d{6}$:
deben coincidir NO deben coincidir
PED-000001 PED-00001 (demasiado corto)
PED-999999 PED-1234567 (demasiado largo)
ped-123456 (mayúsculas)
PED-123456\n (salto de línea final)
xPED-123456 (prefijo)
PED-123456 (dígito de ancho completo: \d lo acepta en Python y .NET)
La lista negativa es la que más aporta. Incluye texto vacío, solo espacios, la longitud máxima más uno, letras no ASCII y un valor válido seguido de texto extra. Cuando el patrón pase, copia ambas listas a un test unitario.
Revisa los grupos y prueba los reemplazos
Los probadores muestran cada coincidencia con sus grupos de captura y posiciones. Comprueba que cada grupo capturó lo que pretendías. Un grupo opcional que no participó devuelve undefined en JavaScript, None en Python y un string vacío en PHP.
La sintaxis de reemplazo cambia en cada lenguaje, así que pruébala en el modo de sustitución del probador con el motor correcto:
JavaScript 'Pérez, Ana'.replace(/(\p{L}+), (\p{L}+)/u, '$2 $1') // 'Ana Pérez'
Python re.sub(r'(\w+), (\w+)', r'\2 \1', 'Pérez, Ana')
PHP preg_replace('/(\w+), (\w+)/u', '$2 $1', 'Pérez, Ana');
Java "Pérez, Ana".replaceAll("(\\w+), (\\w+)", "$2 $1");
Cuidado con las letras con tilde: en JavaScript, \w solo cubre [A-Za-z0-9_] incluso con el flag u, así que 'Pérez, Ana'.replace(/(\w+), (\w+)/u, '$2 $1') devuelve PéAna rez. Por eso el ejemplo usa \p{L}. En PHP con el modificador /u y en Python 3, \w sí incluye é y ñ.
Llevar el patrón al código: el escapado
El probador muestra el patrón tal como lo ve el motor. Tu código lo envuelve en un literal de string, que tiene sus propias reglas de escape. Este paso rompe más patrones que ningún otro.
patrón en el probador: \d+\.\d{2}
JavaScript literal /\d+\.\d{2}/ tal cual
JavaScript string new RegExp('\\d+\\.\\d{2}') cada \ duplicada
Python r'\d+\.\d{2}' string raw: tal cual
Java "\\d+\\.\\d{2}" cada \ duplicada
PHP '/\d+\.\d{2}/' delimitadores; comillas simples
En Java y en new RegExp() de JavaScript, olvidar duplicar una barra convierte \d en d o \. en .. El patrón compila y coincide con otras cosas. Si una regex se comporta distinto en el código que en el probador, imprime el patrón en tiempo de ejecución y pega eso en el probador.
Si el patrón incluye texto del usuario, escápalo siempre: re.escape() en Python, Pattern.quote() en Java, preg_quote() en PHP y, en JavaScript, RegExp.escape() donde esté disponible.
Comprueba el rendimiento antes de publicar
Muchos probadores indican cuántos pasos necesitó una coincidencia o cortan los patrones descontrolados. Prueba tu patrón con un texto largo que casi coincide, por ejemplo 30 letras a seguidas de ! para un patrón con cuantificadores anidados. Si los pasos se disparan, el patrón es vulnerable a backtracking catastrófico (ReDoS) y una sola petición puede ocupar un núcleo del servidor. Elimina cuantificadores anidados o solapados, ancla el patrón y limita la longitud de la entrada.
Fuentes y lecturas recomendadas
La guía de expresiones regulares de MDN (JavaScript), la documentación del módulo re de Python, la documentación de patrones de PCRE2, el Javadoc de java.util.regex.Pattern, la referencia de expresiones regulares de .NET y la página de sintaxis de RE2 documentan las diferencias entre motores. La página de OWASP sobre ReDoS describe el backtracking catastrófico.
Frequently asked questions
¿Cómo pruebo una expresión regular online?
Pega el patrón en un probador de regex, elige el motor y los flags de tu código y pega un texto con casos que deben coincidir y casos que no. Revisa las coincidencias y los grupos, y copia los casos a un test unitario.
¿Por qué mi regex funciona en el probador pero no en mi código?
Normalmente cambian el motor o los flags, o las barras invertidas no se escaparon para el literal de string. Imprime el patrón en tiempo de ejecución y compáralo en el probador con los mismos ajustes.
¿Qué motor de expresiones regulares debo elegir?
El que usa tu código: JavaScript para navegadores y Node.js, Python para `re`, PCRE para PHP, Java para `java.util.regex`, .NET para C# y RE2 para Go.
¿Cómo uso expresiones regulares en JavaScript?
Con un literal `/patrón/flags` o con `new RegExp('patrón', 'flags')`. `test()` devuelve verdadero o falso, `match()` y `matchAll()` devuelven coincidencias y `replace()` sustituye con `$1`, `$2`.
¿Cómo uso expresiones regulares en Python?
Con el módulo `re` y strings raw (`r'\d+'`). Usa `re.fullmatch()` para validar el texto completo, `re.search()` para buscar y `re.sub()` para reemplazar.
¿Cómo uso expresiones regulares en Java?
Compila el patrón con `Pattern.compile("\\d+")`, duplicando cada barra invertida del literal, y obtén un `Matcher` con `pattern.matcher(texto)`. `matches()` exige que coincida el texto completo, `find()` busca la siguiente coincidencia y `replaceAll()` sustituye usando `$1` para los grupos.