ciao a tutti voglio una soluzione per questa espressione regolare, il mio problema è estrarre tutti i numeri esadecimali nel modulo H"xxxx
, ho usato questo regexp ma non ho ricevuto tutti gli esagoni, ho solo un numero, come ottenere un numero esadecimale intero da questa stringa
set hex "V5CCH,IA=H"22EF&H"2354&H"4BD4&H"4C4B&H"4D52&H"4DC9"
set res [regexp -all {H"([0-9A-Z]+)&} $hex match hexValues]
puts "$res H$hexValues"
sto ottenendo l'uscita è 5 H4D52
risposte:
21 per risposta № 1Sopra -all -inline
A partire dal la documentazione:
-all
: Provoca la corrispondenza dell'espressione regolare il maggior numero di volte possibile nella stringa, restituendo il numero totale di corrispondenze trovate. Se questo è specificato con le variabili di corrispondenza, conterranno informazioni solo per l'ultima partita.
-inline
: Fa sì che il comando restituisca, come elenco, i dati che verrebbero altrimenti inseriti nelle variabili di corrispondenza. Quando si usa-inline
, le variabili di corrispondenza potrebbero non essere specificate. Se utilizzato con-all
, l'elenco verrà concatenato ad ogni iterazione, in modo tale viene sempre restituito un elenco semplice. Per ogni iterazione di corrispondenza, il comando aggiungerà i dati di corrispondenza complessivi, più un elemento per ogni sottoespressione nell'espressione regolare.
Pertanto, per restituire tutte le partite, comprese le acquisizioni per gruppi, come una lista piatta in Tcl, puoi scrivere:
set matchTuples [regexp -all -inline $pattern $text]
Se il modello ha gruppi 0…N-1
, quindi ogni corrispondenza è un N
-tupla nell'elenco. Pertanto il numero di corrispondenze effettive è la lunghezza di questo elenco diviso per N
. È quindi possibile utilizzare foreach
con N
variabili da scorrere su ciascuna tupla dell'elenco.
Se N = 2
ad esempio, hai:
set numMatches [expr {[llength $matchTuples] / 2}]
foreach {group0 group1} $matchTuples {
...
}
Riferimenti
Codice di esempio
Ecco una soluzione per questo problema specifico, annotata con output come commenti (guarda anche su ideone.com):
set text "V5CCH,IA=H"22EF&H"2354&H"4BD4&H"4C4B&H"4D52&H"4DC9"
set pattern {H"([0-9A-F]{4})}
set matchTuples [regexp -all -inline $pattern $text]
puts $matchTuples
# H"22EF 22EF H"2354 2354 H"4BD4 4BD4 H"4C4B 4C4B H"4D52 4D52 H"4DC9 4DC9
# _________/ _________/ _________/ _________/ _________/ _________/
# 1st match 2nd match 3rd match 4th match 5th match 6th match
puts [llength $matchTuples]
# 12
set numMatches [expr {[llength $matchTuples] / 2}]
puts $numMatches
# 6
foreach {whole hex} $matchTuples {
puts $hex
}
# 22EF
# 2354
# 4BD4
# 4C4B
# 4D52
# 4DC9
Sul modello
Nota che ho leggermente modificato il motivo:
- Invece di
[0-9A-Z]+
, per esempio.[0-9A-F]{4}
è più specifico per la corrispondenza esatta di 4 cifre esadecimali - Se insisti per abbinare il
&
, quindi l'ultima stringa esadecimale (H"4DC9
nel tuo input) non può essere abbinato- Questo spiega perché ottieni
4D52
nello script originale, perché questa è l'ultima partita con&
- Forse sbarazzarsi di
&
, o usare(&|$)
invece, cioè a&
o la fine della stringa$
.
- Questo spiega perché ottieni
Riferimenti
2 per risposta № 2
Non sono Tclish, ma penso che sia necessario utilizzare entrambi -inline
e -all
opzioni:
regexp -all -inline {H"([0-9A-Z]+)&} $string
EDIT: Eccolo di nuovo, questa volta con una regex corretta (vedi i commenti):
regexp -all -inline {H"[0-9A-F]+&} $string