Búsqueda de expresiones regulares multilínea en archivo completo

He encontrado un montón de ejemplos para reemplazar texto en archivos usando expresiones regulares. Sin embargo, todo se reduce a dos versiones:
1. Iterar sobre todas las líneas en el archivo y aplicar expresiones regulares a cada línea única
2. Cargar el archivo completo.

No. 2 No es posible usar “mis” archivos, son aproximadamente 2GiB …
En cuanto al número 1: actualmente este es mi enfoque, sin embargo, me preguntaba … ¿Qué sucede si se necesita aplicar una expresión regular que abarque más de una línea?

Aquí está la respuesta:
No hay manera fácil

Encontré una clase StreamRegex que podría hacer lo que estoy buscando.
De lo que pude captar del algoritmo:

  • Comience al principio del archivo con un búfer vacío
  • hacer
    • agregar una parte del archivo al búfer
    • si hay una coincidencia en el búfer
      • marcar el partido
      • elimine todos los datos que aparecieron antes del final de la coincidencia desde el búfer
  • ) Mientras aún queda algo del archivo

De esa forma no es necesario cargar el archivo completo, o al menos las posibilidades de cargar el archivo completo en la memoria se reducen …
Sin embargo, el peor de los casos es que no hay coincidencia en todo el archivo; en este caso, el archivo completo se cargará en la memoria.

Regex no es el camino a seguir, especialmente con estas grandes cantidades de texto. Crea un pequeño analizador por tu cuenta:

  • leer el archivo línea por línea;
  • para cada linea:
    • recorre la línea char por char manteniendo el seguimiento de cualquier apertura / cierre de literales de cadena
    • cuando encuentre ‘/ *’ (y no esté ‘dentro’ de una cadena), almacene ese número y bucle de compensación hasta que encuentre el primer ‘* /’ y también almacene ese número

Eso le dará todos los números de inicio y cierre de desplazamiento de los bloques de comentarios. Ahora deberías poder reemplazarlos creando un archivo temporal y escribiendo el texto del archivo original en el archivo temporal (y escribiendo algo más si estás dentro de un bloque de comentarios, por supuesto).

Edición: archivos fuente de 2GiB ??

Tal vez podría cargar 2 líneas a la vez (o más, dependiendo de cuántas líneas cree que van a abarcar sus coincidencias) y superponerlas, por ejemplo: cargar líneas 1-2, luego las líneas de carga del siguiente bucle 2-3 , la siguiente carga 3-4; y haga sus expresiones regulares de varias líneas en ambas líneas combinadas, en cada bucle.

Yo diría que debería realizar un análisis previo / normalización de los datos antes de realizar los reemplazos, de modo que cada línea describa un posible conjunto de datos a los que se deben aplicar los reemplazos. De lo contrario, tendrá complicaciones con la integridad de los datos que realmente no se pueden resolver sin una serie de otras dificultades.

Si hay una manera de dividir los datos en bloques lógicos, entonces podría crear un progtwig que use un patrón mapreduce para analizar los datos.

Estoy con bart Realmente deberías usar algún tipo de analizador para esto.

O, si no te importa generar un proceso secundario, puedes usar sed (hay un puerto nativo en Windows o puedes usar Cygwin )

Si no te importa ensuciarte un poco las manos (y tu expresión regular es lo suficientemente simple, o tal vez tienes un fuerte deseo de velocidad y no te importa sufrir un poco), puedes usar Ragel . Puede apuntar a C #, aunque el sitio no lo menciona. Tendrá que envolver un FileStream para proporcionar un indexador con almacenamiento intermedio o usar un archivo asignado en la memoria (con punteros no seguros) en un proceso de 64 bits para usarlo con archivos grandes.