/ / Come estraggo tutte le partite con un regex Tcl? - regex, tcl

Come estrarre tutte le corrispondenze con una regex Tcl? - regex, tcl

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 № 1

Sopra -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 $.

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