View Full Version : [VB.NET] Colorare stringa contenuta fra due caratteri in una RichtTextBox
Salve,
Come da titolo, sto cercando, cercando su internet e su questo forum, di colorare una stringa in un componente RichTextBox.
Ora vi spiego meglio la mia situazione:
Io avrei un componente RichtTextBox vuota e riempita da codice, nel momento in qui l'utente avvia il forum.
Vorrei che, in quel preciso momento, al caricamento del forum, il componente colori una stringa presente fra due caratteri, decisi ovviamente da me.
Non saprei se mi sono ben spiegato, ma come potrei fare per risolvere il problema?
Semplice.
Soluzione veloce veloce, anche se ammetto non sia il massimo dell'eleganza.
Poniamo di avere una RTB con del testo, e di voler colorare in rosso la stringa compresa tra la prima e la seconda occorrenza del carattere "*" :
Dim inizio As Integer = -1
Dim fine As Integer = -1
Dim strL As Integer = 0
For i As Integer = 0 To RTB.TextLength
If RTB.Text(i) = "*" And inizio = -1 Then
inizio = i + 1
ElseIf RTB.Text(i) = "*" And inizio > -1 Then
fine = i
Exit For
End If
Next
strL = fine - inizio
RTB.Select(inizio, strL)
RTB.SelectionColor = Color.Red
;)
Ho provato con il tuo codice, colora solo la prima occorrenza che trova, di caratteri presenti tra due asterischi ( non so se mi spiego bene )
Ho anche provato a modificare il codice, ma niente, non mi viene restituito il risultato che io vorrei.
In poche parole, non so se mi sono spiegato bene, se vuoi magari rispiego, vorrei che mi colorasse, non solo la prima stringa fra i due asterischi che trova, ma anche le altre, e possibilmente anche gli asterischi, cmq, grazie per aver risposto.
Ma infatti io l'avevo detto che colorava solo la Prima Occorrenza.
E nel post d'apertura non sei stato certo esaustivo.
Quello che chiedi non è poi così scontato. Se ad esempio abbiamo una stringa tipo :
*123*456*789*ABC*DEF*
Quale deve essere il risultato ?
Perchè se vuoi tutte le occorrenze, come dici tu, alla fine tutta la stringa sarà rossa, e non ne vedo l'utilità.
Oppure si potrebbe interpretare come "tutte le occorrenze non consecutive", e in quel caso avrei 2 sotto-casi :
1. Occorrenze non-consecutive-dispari :
*123*456*789*ABC*DEF*
2. Occorrenze non-consecutive-pari :
*123*456*789*ABC*DEF*
3. Oppure, oltre ai caratteri di demarcazione (*) esistono spazi tra una parola e l'altra, e la stringa da analizzare è sempre e solo di questo tipo :
123 *456* 789 *ABC* DEF
...
Come vedi la soluzione non è poi così ovvia. ;)
Scusa, hai ragione, infatti nel mio primo messaggio mi sono spiegato male.
Il fatto è che io avrei bisogno di colorare del codice html.
In poche parole vorrei fare quello che applicano gran parte degli editor al testo ( non so se mi spiego ).
Ho provata anche in alcuni modi a farlo ( mi dispiace ma non ho più il codice precedentemente provato ), ma non ho ottenuto nessun risultato.
L'unica cosa che puoi fare, dato che non hai più nemmeno una linea di codice, è andare per esempi.
Posta alcune stringhe-tipo iniziali e la relativa formattazione desiderata ( come ho fatto io nel post precedente )... ;)
Più che altro, dovrei rappresentare del codice html, come alcuni editor html lo colorano, in questo modo:
<html>
<head>
<title>Titolo</title>
<body>
testo testo testo
</body>
</html>
In poche parole dovrei colorare tutte le stringe contenuti fra il carattere < e >.
Più che altro, dovrei rappresentare del codice html, come alcuni editor html lo colorano, in questo modo:
<html>
<head>
<title>Titolo</title>
<body>
testo testo testo
</body>
</html>
In poche parole dovrei colorare tutte le stringe contenuti fra il carattere < e >.
Eh, no.
La fai troppo semplice.
Potresti lavorarci con :
Dim tagHtml As String = "<html>"
RichTextBox1.SelectionStart = RichTextBox1.Find(tagHtml)
RichTextBox1.SelectionLength = tagHtml.Length
RichTextBox1.SelectionColor = Color.Blue
Ma devi prevedere anche i casi particolari, come questo :
<h1>Questo <html> non dovrebbe essere colorato</h1>
Non è così immediato come pensi... ;)
Più che altro io avevo semplicemente pensato di colorare tutte le occorrente di caratteri fra il carattere < e > per evitare di scrivere direttamente tutti i tag html da colorare ( che sono tanti, e nemmeno so se li so tutti ).
Non so, te cosa mi consigli, sapendo quello che ti ho detto?
Inizia con lo studio delle Regex ( Regular Expressions ). Saranno sicuramente utili allo scopo...
Personalmente non ho mai avuto la necessità di fare niente del genere, perciò non ho codice "pronto all'uso" da suggerire...
E' un quesito da cui possono nascere spunti interessanti.
Bisognerebbe creare un piccolo parser, usando un automa a stati finiti ed uno stack ce la potresti fare.
Supponiamo di voler colorare tutti i tag che siano correttamente chiusi, ovvero che compaiono a coppia (<tag>qualcosa</tag>).
Faremo uso di uno stack di code. Ovvero faremo una pila di questo tipo:
|___| <- top dello stack
|___|
|___|
|___|
I cui elementi saranno "code" di caratteri (quelli che incontriamo).
Esempio, incontriamo le parole "asd" e "bla"
Il nostro stack sarà così fatto:
|[alb] | <- top dello stack
|[dsa]|
(le code crescono verso sinistra, il primo della coda è a destra)
A questo punto possiamo fare una cosa di questo tipo:
Chiamiamo S lo stack e Q la coda di caratteri corrente.
Stato 0 => stato iniziale
se leggo '<': creo una nuova coda Q e passo allo stato 1
altrimenti rimango nello stato 0
Stato 1 => letto '<'
se leggo '>' aggiungo la coda Q sullo stack, vai a Stato0
se leggo '/' vai a Stato2
altrimenti aggiungi il carattere alla coda Q, rimani in Stato1
Stato 2 => Q è il top dello stack
se il primo carattere nella coda è uguale a quello letto in input: rimuovo il carattere dalla coda.
se leggo '>' e la coda è vuota: rimuovo la coda corrente Q dal top dello stack ed evidenzio i tag, passo allo stato 0.
se leggo '>' ma la coda non è vuota significa che c'è un errore di sintassi, non devo evidenziare nulla, a quel punto il riconoscimento è compromesso (bisognerebbe gestire questa situazione per portare il parser ad uno stato utilizzabile).
Esempio con la stringa:
"prova <asd>questo <html> va una bomba</asd>"
Chiaramente si rimane nello stato0 fino a quando non incontro il primo '<'.
I successivi caratteri (a, s, d) verranno aggiunti alla coda Q, risultando Q=[d, s, a] dove a è il primo della coda.
Leggendo '>' Q viene aggiunto allo stack.
La cosa si ripete per <html>, quindi avremo uno stack con 2 elementi:
[l, m, t, h] <-- top dello stack
[d, s, a]
A questo punto è evidente che quando incontriamo l'ultimo tag </asd> troveremo un errore, perché ci aspetteremmo di trovare </html>.
Quindi in questo caso nessuno dei tag verrà evidenziato.
Viceversa togliendo <html> dal mezzo della stringa, avremmo che lo stack contiene solo [d, s, a] e dopo aver letto la sequenza "</" ci troveremmo nello Stato2, per cui:
Leggiamo 'a', Q diventa [d, s]
Leggiamo 's', Q diventa [d]
Leggiamo 'd', Q diventa [] (coda vuota)
Leggendo '>' accettiamo perché la coda è vuota ed evidenziamo i tag.
Ora chiaramente questa cosa voleva essere di esempio, ma credo si possa facilmente adattare per il tuo problema, per quanto comunque tutto ciò non sia così banale.
Stesso stabilire in quale caso vuoi evidenziare i tag può cambiare di molto le cose.
Domani provo a divertirmi un po' implementando ciò che chiedi :D.
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.