Cómo crear, probar y revisar regex con Claude Code
Guía práctica para crear y revisar regex con Claude Code: email, teléfono, logs, capturas con nombre y pruebas.
Las expresiones regulares fallan con frecuencia cuando el requisito está poco definido. Un patrón que acepta user@example.com puede rechazar user+tag@sub.example.co.jp, aceptar por error user@.com o volverse difícil de revisar cuando se añade otro grupo de captura.
Claude Code ayuda porque convierte ejemplos en un flujo verificable: cadenas permitidas, cadenas rechazadas, regex, pruebas ejecutables y una lista de revisión. Una expresión regular describe la forma de un texto. Una captura con nombre permite extraer partes con nombres legibles como timestamp o requestId.
Si estás empezando, revisa primero la guía de inicio de Claude Code. Para escribir mejores encargos, conecta esta guía con 5 consejos para mejores prompts. Como referencias oficiales, conviene tener abiertos Claude Code overview y MDN Regular expressions.
Flujo recomendado
flowchart LR
A["Ejemplos permitidos"] --> C["Pedir a Claude Code"]
B["Ejemplos rechazados"] --> C
C --> D["Regex y helpers"]
D --> E["Pruebas Node.js"]
E --> F["Revisión de riesgos"]
No pidas solo “un regex de email”. Indica si lo usarás para validar, extraer, reemplazar o analizar logs. Los ejemplos se convierten en el contrato que las pruebas protegen.
Primer prompt
Crea un helper JavaScript de regex para emails, teléfonos japoneses y logs de aplicación.
Requisitos:
- Debe ejecutarse directamente en Node.js
- Permitir user+tag@sub.example.co.jp
- Rechazar user..name@example.com y user@.com
- Permitir 090-1234-5678, 03-1234-5678 y 05012345678
- Extraer timestamp, level, service, requestId y message de logs con capturas con nombre
- Añadir pruebas con node:test
- Explicar dónde no conviene sustituir validación de negocio por regex
La clave es el alcance. La validación completa de emails según RFC rara vez es lo que necesita un formulario. Aquí buscamos una regla práctica que bloquee errores obvios y deje la entregabilidad a un correo de confirmación o a una comprobación backend.
Ejemplo 1: Helper de email, teléfono y logs
Guárdalo como regex-helper.mjs y ejecuta node regex-helper.mjs.
import { fileURLToPath } from "node:url";
export const emailRegex =
/^(?!.*\.\.)[A-Z0-9_%+-]+(?:\.[A-Z0-9_%+-]+)*@(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,63}$/i;
export const emailSearchRegex =
/[A-Z0-9_%+-]+(?:\.[A-Z0-9_%+-]+)*@(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,63}/gi;
export const normalizedJapanesePhoneRegex = /^0(?:[5789]0\d{8}|[1-9]\d{8,9})$/;
export const looseJapanesePhoneSearchRegex =
/0\d{1,4}[-\s]?\d{1,4}[-\s]?\d{3,4}/g;
export const appLogRegex =
/^\[(?<timestamp>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?Z)\]\s+(?<level>INFO|WARN|ERROR)\s+(?<service>[a-z][a-z0-9-]*)\s+requestId=(?<requestId>[A-Za-z0-9_-]+)\s+message="(?<message>[^"]*)"$/;
export function isEmail(input) {
return emailRegex.test(input.trim());
}
export function normalizePhone(input) {
return input.replace(/[()\s-]/g, "");
}
export function isJapanesePhone(input) {
return normalizedJapanesePhoneRegex.test(normalizePhone(input));
}
export function extractContacts(text) {
const emails = [...text.matchAll(emailSearchRegex)]
.map((match) => match[0])
.filter(isEmail);
const phones = (text.match(looseJapanesePhoneSearchRegex) ?? []).filter(
isJapanesePhone,
);
return {
emails: [...new Set(emails)],
phones: [...new Set(phones)],
};
}
export function parseLogLine(line) {
const match = line.match(appLogRegex);
if (!match?.groups) return null;
return {
timestamp: match.groups.timestamp,
level: match.groups.level,
service: match.groups.service,
requestId: match.groups.requestId,
message: match.groups.message,
};
}
if (process.argv[1] === fileURLToPath(import.meta.url)) {
const text = "Contact: user+tag@sub.example.co.jp / 090-1234-5678";
const log =
'[2026-06-02T10:15:30.000Z] ERROR billing-api requestId=req_123 message="payment failed"';
console.log(extractContacts(text));
console.log(parseLogLine(log));
}
Los teléfonos se normalizan antes de validar. Así el patrón es más simple y 090-1234-5678 se puede comparar con 090 1234 5678. En logs usamos capturas con nombre para leer match.groups.requestId en lugar de adivinar qué significa match[4].
Ejemplo 2: Pruebas que fijan el comportamiento
Guárdalo como regex-helper.test.mjs y ejecuta node --test regex-helper.test.mjs.
import test from "node:test";
import assert from "node:assert/strict";
import {
extractContacts,
isEmail,
isJapanesePhone,
parseLogLine,
} from "./regex-helper.mjs";
test("validates practical email addresses", () => {
assert.equal(isEmail("user@example.com"), true);
assert.equal(isEmail("user+tag@sub.example.co.jp"), true);
assert.equal(isEmail("user..name@example.com"), false);
assert.equal(isEmail("user@.com"), false);
assert.equal(isEmail("@example.com"), false);
});
test("validates Japanese phone numbers after normalization", () => {
assert.equal(isJapanesePhone("090-1234-5678"), true);
assert.equal(isJapanesePhone("03-1234-5678"), true);
assert.equal(isJapanesePhone("05012345678"), true);
assert.equal(isJapanesePhone("123-4567-8901"), false);
assert.equal(isJapanesePhone("090-123-456"), false);
});
test("extracts contacts from free text", () => {
assert.deepEqual(
extractContacts("support: user+tag@example.com, tel: 090-1234-5678"),
{
emails: ["user+tag@example.com"],
phones: ["090-1234-5678"],
},
);
});
test("parses application logs with named captures", () => {
const parsed = parseLogLine(
'[2026-06-02T10:15:30.000Z] WARN auth-service requestId=req_abc message="retry required"',
);
assert.deepEqual(parsed, {
timestamp: "2026-06-02T10:15:30.000Z",
level: "WARN",
service: "auth-service",
requestId: "req_abc",
message: "retry required",
});
});
Pide a Claude Code que ejecute la prueba.
Ejecuta node --test regex-helper.test.mjs.
Si falla, explica primero si está mal la regex o el dato de prueba.
Si amplías el soporte de emails, añade antes un ejemplo permitido y otro rechazado.
Ejemplo 3: Prompt para extracción de logs
Los logs son un buen caso para regex porque el formato lo controla la aplicación.
Lee logs/app.log, extrae solo las líneas ERROR y escribe requestId y message en un CSV.
Usa el mismo appLogRegex que regex-helper.mjs.
No descartes en silencio las líneas que no se puedan parsear; informa el conteo al final.
No escribas emails ni teléfonos en el CSV.
En producción siempre aparecen líneas antiguas, cortadas o con formato temporal. Un parser que devuelve null es más fácil de revisar que un script que ignora datos sin avisar.
Plantilla de revisión
## Regex review request
Files:
- regex-helper.mjs
- regex-helper.test.mjs
Review:
- Are allowed and rejected examples covered by tests?
- Are email, phone, and log responsibilities separated?
- Are named capture names readable?
- Is there any ambiguous repetition that could cause ReDoS?
- Could personal data leak into logs or CSV output?
Output:
- For each issue, include file, line, reason, and suggested fix
- Ask a question instead of guessing when the business rule is unclear
- Run node --test regex-helper.test.mjs after changes
ReDoS significa que una expresión regular puede tardar demasiado con una entrada preparada. Si hay repeticiones anidadas, pide a Claude Code que lo revise explícitamente.
Errores comunes
| Error | Mejor instrucción |
|---|---|
| Dar solo ejemplos válidos | Añadir al menos 3 ejemplos rechazados |
Usar .* para todo | Usar límites concretos como [^"]* |
Reutilizar una regex con g y test() | Separar regex de validación y de búsqueda |
| Depender de índices de captura | Usar capturas con nombre o grupos no capturantes |
| Confundir regex con validación de negocio | Validar entregabilidad y existencia en backend |
Regex es útil para dar forma a entradas y extraer datos de texto controlado. No demuestra que un email reciba correo, que un teléfono exista o que un requestId esté en la base de datos.
CTA
Mejorar regex impacta formularios de leads, logs de pago, soporte y descargas. Para practicar, empieza con la chuleta gratuita de Claude Code. Para plantillas reutilizables, revisa productos. Si tu equipo necesita reglas de validación, revisión de logs y gates de revisión adaptados a un repositorio real, usa formación y consultoría de Claude Code.
Resumen
La mejor forma de usar Claude Code con regex es entregar ejemplos, contraejemplos, pruebas y criterios de revisión en el mismo ciclo. En la prueba de Masa, pedir “regex y pruebas juntas” detectó antes los casos de user+tag, teléfonos con guiones y capturas de logs con nombre que pedir solo una regex.
PDF gratis: cheatsheet de Claude Code
Introduce tu email y descarga una hoja con comandos, hábitos de revisión y flujos seguros.
Cuidamos tus datos y no enviamos spam.
Sobre el autor
Masa
Ingeniero enfocado en workflows prácticos con Claude Code.
Artículos relacionados
Workflow de Obsidian a CLAUDE.md con Claude Code
Convierte notas de trabajo de Obsidian en notas operativas de CLAUDE.md para no repetir contexto.
Claude Code Revenue CTA Routing: de artículos a PDF, Gumroad y consulta
Un flujo con Claude Code para dirigir lectores a PDF gratis, Gumroad o consulta según intención.
Reglas de handoff para equipos con Claude Code: evidencia, permisos, rollback e ingresos
Formato práctico para entregar trabajo de Claude Code con pruebas, permisos, rollback, PDF gratis, Gumroad y consulta.