Pregunta

Tengo un gran conjunto de líneas de registro y necesito analizar cada línea (para que la eficiencia es muy importante).

Cada línea de registro tiene la forma

cust_name time_start time_end (IP o URL) *

Por lo tanto, la dirección IP, la hora, la hora y una lista posiblemente vacía de direcciones IP o URL separadas por punto y coma. Si solo hay ip o url en la última lista, no hay separador. Sí hay es más de 1, luego están separados por punto y coma.

Necesito una forma de analizar esta línea y leerla en una estructura de datos. time_start o time_end podría ser la hora del sistema o GMT. cust_name también podría tener múltiples cadenas separados por espacios.

Puedo hacer esto leyendo personaje por personaje y esencialmente escribiendo mi propio analizador. ¿Hay una mejor manera de hacer esto?

¿Fue útil?

Otros consejos

He tenido éxito con Boost Tokenizer para este tipo de cosas. Le ayuda a dividir una secuencia de entrada en tokens con separadores personalizados entre los tokens.

Usando expresiones regulares ( boost :: regex es una buena implementación para C ++) puede separar fácilmente diferentes partes de su cadena - cust_name, time_start ... y buscar todas las direcciones URL \ ips

El segundo paso es un análisis más detallado de esos grupos si es necesario. Las fechas, por ejemplo, puede analizar utilizando la biblioteca boost :: datetime (escribir un analizador personalizado si el formato de cadena no es estándar).

¿Por qué quieres hacer esto en C ++? Parece un trabajo obvio para algo como Perl.

Considere utilizar una biblioteca de expresiones regulares ...

La entrada personalizada exige un analizador personalizado. O reza para que haya un mundo ideal y no existan errores. Especialmente, si quieres tener eficiencia. Publicar algún código puede ser de ayuda.

para una gramática tan simple que puede usar split, eche un vistazo a http://www.boost.org/doc/libs/1_38_0/doc/html/string_algo/usage.html#id4002194

¡

ACTUALIZACIÓN cambió la respuesta drásticamente!

  

Tengo un gran conjunto de líneas de registro y necesito analizar cada línea (por lo que la eficiencia es muy importante).

Solo tenga en cuenta que C ++ no ayudará mucho en términos de eficiencia en esta situación. ¡No se deje engañar y pensar que solo porque tenga un código de análisis rápido en C ++, su programa tendrá un alto rendimiento!

La eficiencia que realmente necesita aquí no es el rendimiento en el " código de máquina " nivel del código de análisis, pero en el nivel general del algoritmo.

Piensa en lo que estás tratando de hacer.
Tiene un archivo de texto enorme y desea convertir cada línea en una estructura de datos,

El almacenamiento de enorme en la memoria es muy ineficaz , ¡no importa qué idioma esté usando!

Lo que debe hacer es "buscar" una línea a la vez, conviértala en una estructura de datos y trátela, entonces, y solo después de que haya terminado con la estructura de datos, vaya a buscar la siguiente línea y la convierta en una estructura de datos, trátela , y repetir.

Si haces eso, ya has resuelto el principal cuello de botella.

Para analizar la línea de texto, parece que el formato de sus datos es bastante simplista, verifique una pregunta similar que hice hace un tiempo: C ++ string parsing (estilo de python)

En su caso, supongo que podría usar un flujo de cadena y utilizar el operador > > para leer la siguiente cosa " " en la linea.

vea esta respuesta para el código de ejemplo.

Alternativamente, (¡no quería eliminar esta parte!) Si pudieras escribir esto en Python, sería mucho más simple. No sé tu situación (parece que estás atrapado con C ++), pero aún así

Mire esta presentación para realizar este tipo de tareas de manera eficiente utilizando expresiones generadoras de Python: http: / /www.dabeaz.com/generators/Generators.pdf

Vale la pena leerlo. En la diapositiva 31 se ocupa de lo que parece ser algo muy similar a lo que estás tratando de hacer.

Al menos te dará algo de inspiración.
También demuestra claramente que el rendimiento se obtiene no por el código de análisis de cadena en particular, sino por el algoritmo general.

Puedes intentar usar un vocabulario simple lex / yacc | flex / bison para analizar este tipo de información.

El analizador que necesitas suena realmente simple. Mire esto. Cualquier lenguaje compilado debe poder analizarlo en Muy alta velocidad. Entonces es una cuestión de qué estructura de datos construye & amp; guardar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top