Cómo separar una cadena con calificadores de texto

Recientemente trabajé en un proyecto para importar un archivo separado por comas (CSV) para cargar los datos a una table en una base de datos.

En mi búsqueda por encontrar una solución facil para resolver esta necesidad, me encontré con TinyCSVParser, que me funciono de maravilla. es algo elaborado configurar pero al final terminé con una solución rasonablemente aceptable. El problema que me encontré es que para cargar un archivo de 25 MB la aplicación cargaba en memoria 1GB aproximadamente.

No estuve contento con el resultado y me dediqué a buscar otra solucion… si tan solo existiera una forma de separar una cadena de texto podría cargar el archivo a memoria, leer linea por linea y cada linea separarla. Un simple Split no era suficiente ya que los registros en el archivo contenian comillas dobles como calificador ya que el contenido de algunas columnas contenian comas dentro.

La solución, combinar el uso del Split con expresiones regulares. Busncando me encontre con una cadena que me permite separar por comar y especificar como calificador las comillas dobles:

stringLineaPorSeparar = @"105,10788114,""NOZ,QF - SBN - 3,7 / 32"",A,FG Inv,N,$2.16";
Regex objetoSeparador = new Regex(",(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))");
var lineaSeparada = objetoSeparador.Split(stringLineaPorSeparar);

Lo anterior me dia la idea de aplicar una mejora en la que podia especificar el separadory el calificador

public static IList<string> ObtenColumnas(string stringLineaPorSeparar, char separador = ',', char calificador = '\"')
        {
            //Definir el objeto con la expresion regular que contiene nuestro separador y calificador de texto
            Regex objetoSeparador = new Regex(separador + "(?=(?:[^" + calificador + "]*" + calificador + "[^" + calificador + "]*" + calificador + ")*(?![^" + calificador + "]*" + calificador + "))");
            
            //Separar lania de texto usando nuestra expresion regular
            var lineaSeparada = objetoSeparador.Split(stringLineaPorSeparar);

            //objeto que regresa nuestro metodo
            return lineaSeparada;
        }

En mis prubeas, esta solucion carga alrededor de 120 MB lo que es significativamente mejor, ademas de ser muy rápido.

Espero esta solución les sea útil.