Posizionare marcatori di testo all'interno di stringhe in cattivo stile? C'è un'alternativa?

10

Lavoro con stringhe massive che richiedono molta manipolazione.

Ad esempio, potrei generare una stringa come questa:

Part 1
Boat

Section A
Programming

Part 2
Partitioning boats for programming.

Section AA
Section SQL Entries.

La stringa sarebbe troppo grande per controllarne manualmente ogni parte. Ora ho bisogno di split this string in stringlist per sezioni e parti. Posso pensare a due opzioni:

Un'espressione regolare:

QStringList sl = s.split(QRegularExpression("\n(?=Part [0-9]+|Section [A-Z]+)"));

Sembra che dovrebbe funzionare, ma a volte scivolano le eccezioni (IE: Section SQL Entries viene erroneamente diviso)

Altrimenti quello che potrei fare è posizionare un marcatore quando genero la stringa iniziale:

posta Akiva 21.11.2016 - 13:20
fonte

5 risposte

17

Non è una cattiva pratica avere la codifica dei documenti incorporata come testo in una stringa. Pensa a markdown, HTML, XML, JSON, YAML, LaTeX, ecc.

Ciò che è una cattiva pratica è reinventare la ruota. Piuttosto che scrivere il tuo processore di testo, pensa a utilizzare uno standard esistente. C'è un sacco di software libero che fa gran parte del lavoro di analisi per te, e molti hanno una licenza non restrittiva che ti consente di utilizzare tale software nel tuo software proprietario.

    
risposta data 21.11.2016 - 13:32
fonte
8

L'utilizzo di un separatore comune dovrebbe funzionare correttamente quando si suddividono stringhe arbitrarie più grandi, ma è consigliabile non utilizzare un simbolo arbitrario. Qualcuno che legge quella stringa come testo in chiaro potrebbe essere confuso, per non parlare dei problemi con UTF e se il simbolo appare o meno all'interno delle sezioni o meno.

La parte più importante di questo è che ogni sezione rimane intatta, mentre ogni "intestazione di sezione" deve essere identificata in modo appropriato.

Perché non utilizzare un separatore comune ma tenerlo leggibile? Qualcosa come:

[SECTION]
Part 1
Boat

[SECTION]
Section A
Programming

[SECTION]
Part 2
Partitioning boats for programming.

[SECTION]
Section AA
Section SQL Entries.

Il problema è decidere cosa dovrebbe essere il separatore , in quanto deve essere garantito che non mostri alcuna sezione. Puoi identificarlo ulteriormente come separatore richiedendo che sia all'inizio di una riga e solo testo su quella riga .

Senza ulteriore conoscenza del testo previsto in ciascuna sezione, è difficile formulare una raccomandazione su quale separatore comune sarebbe il migliore in questo caso.

    
risposta data 21.11.2016 - 13:38
fonte
5

La risposta accettata sembra aver perso ciò che hai scritto in un commento:

The reason is that a lot of the manipulation I do requires the full string

e ha fornito questo come esempio:

s.replace("boat", "programming");

Se è quello che vuoi, è davvero una cattiva idea usare IMHO un "markdown" o un separatore testuale per tutta la tua stringa, questo ha sempre un certo rischio di interferire con la manipolazione e non porterà a codice robusto. Soprattutto quando provi ad iniziare ad usare le espressioni regolari su una tale combinazione, probabilmente incontrerai gli stessi problemi osservati da cercando di analizzare HTLM o XML con le espressioni regolari .

Specialmente perché hai scritto che potrebbero esserci "migliaia di [tali funzioni di manipolazione]", il rischio potrebbe diventare un problema reale. Anche se utilizzi un markdown come XML per archiviare l'elenco di stringhe internamente, devi assicurarti che la manipolazione elabori solo il contenuto, non il markdown, quindi significherebbe dividere la stringa in parti prima di eseguire qualsiasi elaborazione e unire in seguito di nuovo - quindi che avrà un alto rischio di darti una cattiva prestazione.

L'alternativa di design migliore qui è quella di fornire un tipo di dati astratto (usa una classe se vuoi), chiamiamolo MyStringList , e fornire un piccolo insieme di operazioni di base che ti permettono di implementare le tue "migliaia di funzioni" in termini di tali operazioni. Ad esempio, potrebbero esserci generiche operazioni find e replace , oppure un'operazione generica map . Puoi anche aggiungere qualcosa come un'operazione JoinToString se hai davvero bisogno dell'intera lista in una stringa per certi purpers.

Usando queste operazioni, la tua paura che il codice diventi più complicato perché "tutto dovrebbe essere fatto in un ciclo for" diventa inutile, perché gli unici for di cicli che si ottengono sono incapsulati all'interno le operazioni del tipo di dati. E non mi preoccuperei delle prestazioni finché non avremo un impatto reale e misurabile sulle prestazioni (che dubito di ottenere se implementate correttamente le operazioni di base).

    
risposta data 21.11.2016 - 21:13
fonte
1

Il formato descritto è molto simile ai file INI:

link

In questo caso la sezione è racchiusa tra parentesi quadre [], quindi ciò che descrivi ha senso contrassegnando la sezione in qualche modo per aggiungere ulteriore significato a quel testo.

    
risposta data 21.11.2016 - 22:18
fonte
0

For example, I might generate a string like this:

Domanda: da cosa "generi" questa stringa?

Potrebbe che essere più facile da manipolare?

    
risposta data 22.11.2016 - 13:21
fonte