'Bancolombia', 'tipo' => self::detectarTipo($text), 'destinatario' => self::extraer($text, '/Bancolombia[:\s]+([A-ZÁÉÍÓÚÑÜ][A-Za-záéíóúñü\s]+?),\s+recibiste/u'), 'remitente' => self::extraer($text, '/transferencia\s+de\s+(.+?)\s+por\s+\$/iu'), 'valor' => self::extraerValor($text), 'cuenta' => self::extraer($text, '/cuenta\s+\*(\d+)/iu'), 'llave' => self::extraer($text, '/llave\s+([@\w.\-]+)/iu'), 'fecha' => self::extraer($text, '/el\s+(\d{1,2}\/\d{1,2}\/\d{2,4})/iu'), 'hora' => self::extraer($text, '/a\s+las\s+(\d{1,2}:\d{2})/iu'), 'texto_original' => $text, ]; return $result; } // ───────────────────────────────────────────────────────── // Helpers privados // ───────────────────────────────────────────────────────── private static function esBancolombia(string $text): bool { return stripos($text, 'bancolombia') !== false && ( stripos($text, 'transferencia') !== false || stripos($text, 'pago') !== false || stripos($text, 'recibiste') !== false || stripos($text, 'enviaste') !== false ); } private static function detectarTipo(string $text): string { if (stripos($text, 'recibiste') !== false) { return 'transferencia_recibida'; } if (stripos($text, 'enviaste') !== false) { return 'transferencia_enviada'; } if (stripos($text, 'pago') !== false) { return 'pago'; } return 'notificacion'; } /** * Ejecuta un regex y devuelve el primer grupo capturado, trimmed. */ private static function extraer(string $text, string $pattern): string { if (preg_match($pattern, $text, $m)) { return trim($m[1]); } return ''; } /** * Extrae el valor monetario como string limpio, ej: "1000.00" * y también como float. * Devuelve el string formateado con separadores originales. */ private static function extraerValor(string $text): string { // Captura números con puntos y comas: $1,000.00 | $1.000,00 | $500 if (preg_match('/por\s+\$([0-9][0-9.,]*)/iu', $text, $m)) { return trim($m[1]); } return ''; } /** * Elimina completamente bloques