Domanda

Ho un enorme set di linee di log e ho bisogno di analizzare ogni riga (quindi efficienza è molto importante).

Ogni riga del registro ha il formato

cust_name time_start time_end (IP o URL) *

Quindi indirizzo IP, ora, ora e un elenco eventualmente vuoto di indirizzi IP o URL separati da punti e virgola. Se nell'ultimo elenco è presente solo ip o url, non è presente alcun separatore. Se ci è più di 1, quindi sono separati da punti e virgola.

Ho bisogno di un modo per analizzare questa riga e leggerla in una struttura di dati. time_start o time_end potrebbe essere l'ora di sistema o GMT. cust_name potrebbe anche avere più stringhe separati da spazi.

Posso farlo leggendo carattere per carattere e essenzialmente scrivendo il mio parser. C'è un modo migliore per farlo?

È stato utile?

Altri suggerimenti

Ho avuto successo con Boost Tokenizer per questo genere di cose. Ti aiuta a suddividere un flusso di input in token con separatori personalizzati tra i token.

Usando le espressioni regolari ( boost :: regex è una buona implementazione per C ++) puoi facilmente separare diverse parti della tua stringa - cust_name, time_start ... e trovare tutto ciò che url \ ips

Il secondo passaggio è l'analisi più dettagliata di tali gruppi, se necessario. Ad esempio, date che puoi analizzare usando la libreria boost :: datetime (scrivendo un parser personalizzato se il formato stringa non è standard).

Perché vuoi farlo in C ++? Sembra un lavoro ovvio per qualcosa come Perl.

Prendi in considerazione l'utilizzo di una libreria di espressioni regolari ...

L'input personalizzato richiede un parser personalizzato. Oppure, prega che esista un mondo ideale e che non esistano errori. Specialmente, se vuoi avere efficienza. La pubblicazione di alcuni codici potrebbe essere di aiuto.

per una grammatica così semplice che puoi usare split, dai un'occhiata a http://www.boost.org/doc/libs/1_38_0/doc/html/string_algo/usage.html#id4002194

AGGIORNAMENTO ha cambiato drasticamente la risposta!

  

Ho un enorme set di linee di log e ho bisogno di analizzare ogni riga (quindi l'efficienza è molto importante).

Basta essere consapevoli del fatto che C ++ non aiuterà molto in termini di efficienza in questa situazione. Non farti ingannare nel pensare che solo perché hai un codice di analisi veloce in C ++ che il tuo programma avrà prestazioni elevate!

L'efficienza di cui hai veramente bisogno qui non è la prestazione al "codice macchina" livello del codice di analisi, ma a livello di algoritmo generale.

Pensa a cosa stai cercando di fare.
Hai un enorme file di testo e vuoi convertire ogni riga in una struttura di dati,

La memorizzazione di enormi strutture di dati in memoria è molto inefficiente , indipendentemente dalla lingua che stai usando!

Quello che devi fare è " fetch " una riga alla volta, convertila in una struttura di dati e gestiscila, quindi, e solo dopo aver finito con la struttura di dati, vai a recuperare la riga successiva e la converti in una struttura di dati, gestendola e ripeti.

Se lo fai, hai già risolto il principale collo di bottiglia.

Per analizzare la riga di testo, sembra che il formato dei tuoi dati sia abbastanza semplicistico, controlla una domanda simile che ho posto qualche tempo fa: Analisi di stringhe C ++ (stile python)

Nel tuo caso, suppongo che potresti usare un flusso di stringhe e usare l'operatore > > per leggere la prossima cosa " cosa " nella linea.

vedi questa risposta per esempio codice.

In alternativa, (non volevo cancellare questa parte !!) Se potessi scrivere questo in Python sarà molto più semplice. Non conosco la tua situazione (sembra che tu sia bloccato con C ++), ma comunque

Guarda questa presentazione per svolgere questo tipo di attività in modo efficiente utilizzando le espressioni del generatore python: http: / /www.dabeaz.com/generators/Generators.pdf

Vale la pena leggere. Alla diapositiva 31 si occupa di quello che sembra essere qualcosa di molto simile a quello che stai cercando di fare.

Ti darà almeno un po 'di ispirazione.
Dimostra anche abbastanza fortemente che le prestazioni non sono ottenute dal particolare codice di analisi delle stringhe, ma dall'algoritmo globale.

Potresti provare a usare un semplice vocabolario lex / yacc | flex / bison per analizzare questo tipo di input.

Il parser di cui hai bisogno sembra davvero semplice. Dai un'occhiata a questo. Qualsiasi linguaggio compilato dovrebbe essere in grado di analizzarlo su altissima velocità. Quindi è un problema di quale struttura di dati crei & amp; risparmiare.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top