/ / Come utilizzare un'espressione regolare per abbinare un simbolo come una stringa letterale in un oggetto hash? - rubino, regex, hash

Come usare un'espressione regolare per abbinare un simbolo come una stringa letterale in un oggetto hash? - rubino, regex, hash

utilizzando str poiché la chiave nell'hash funziona bene.

string = "The dog and cat"
replace = {"dog" => "woof", "cat" => "meow"}
replace.default = "unknown"

string.gsub(/w+/, replace)
# => "unknown woof unknown meow"

Come ottengo lo stesso risultato con un file sym come la chiave hash?

string = "The dog and cat"
replace = {dog: "woof", cat: "meow"}
replace.default = "unknown"

string.gsub(/w+/, replace)
# => "unknown unknown unknown unknown" (actual result)
# => "unknown woof unknown meow" using symbols as hash keys? (desired result)

Alcuni tentativi che ho fatto:

string.gsub(/(w+)/, replace[:$1])
# => "unknown unknown unknown unknown"

string.split.map(&:to_sym).to_s.gsub(/w+/, replace)
# => "[:unknown, :unknown, :unknown, :unknown]"

risposte:

3 per risposta № 1

Nel codice sottostante:

string = "The dog and cat"
replace = {dog: "woof", cat: "meow"}
replace.default = "unknown"
string.gsub(/w+/, replace)

Hai fatto l'hash replace, valore predefinito come "unknown". Significa, quando cercherete un valore dall'hash replace, se la chiave non è presente, l'hash ti restituirà unknown come valore. Funzionerà in questo modo come hai definito l'hash in questo modo.

Adesso #gsub metodo, dando a tutte le parole corrispondenze come "the", "dog" ecc, ma nessuna di queste stringhe è la chiave per il tuo hash replace, quindi come ho detto sopra, hash replace restituirà ogni volta il valore predefinito unknown.

Ricorda: nell'hash replace = {dog: "woof", cat: "meow"}, le chiavi sono simboli, come :dog, :cat. Ma #gsub ti dà tutta la partita come file stringa.

Quindi per farlo funzionare è necessario utilizzare il blocco come di seguito:

string = "The dog and cat"
replace = {dog: "woof", cat: "meow"}
replace.default = "unknown"
string.gsub(/w+/) { |m| replace[m.to_sym] }
# => "unknown woof unknown meow"

1 per risposta № 2

Se vuoi mantenere tutte le altre parole così come sono, ma semplicemente sostituire ciò che è nell'hash, puoi farlo:

replace = {"dog" => "woof", "cat" => "meow"}
my_string = "The dog and cat"
my_string.gsub(/w+/) {|m| (replace.key? m) ? replace[m] : m}

Che produrrà:

The woof and meow

O in modo più compatto (grazie a @Arup per il suggerimento):

my_string.gsub(/w+/) {|m| replace.fetch(m, m)}

0 per risposta № 3

Non è chiaro il motivo per cui desideri sostituire le parole "sconosciute" con unknown; Non è qualcosa di molto utile nella normalitàcodice di elaborazione di stringhe o di elaborazione di modelli. Di conseguenza sembra che tu "stia facendo una domanda X-Y, volendo sapere come fare" Y "quando dovresti davvero fare" X ".

Ecco del codice e delle informazioni che potrebbero essere utili:

string = "The dog and cat"
replacement_hash = {dog: "woof", cat: "meow"}

Innanzitutto, fai molta attenzione nell'usare una variabile con l'estensionestesso nome di un metodo. Ruby può capire cosa intendi di solito, ma il tuo cervello non riuscirà sempre a stabilire la connessione. Il cervello delle persone che usano o mantengono il tuo codice potrebbero non funzionare altrettanto bene. Quindi, invece di un hash chiamato replace, usa qualcosa come replacement_hash.

Normalmente non vogliamo definire un hash usandosimboli come chiavi se "faremo ricerca e sostituzione di azioni contro una stringa. Invece" vorremmo "i valori di stringa effettivi; È più semplice in questo modo. Detto questo, questo passerà attraverso un hash con simboli come chiavi e genererà un nuovo hash usando le stringhe equivalenti come chiavi:

replacement_hash2 = Hash[replacement_hash.keys.map(&:to_s).zip(replacement_hash.values)] # => {"dog"=>"woof", "cat"=>"meow"}

Noi dare gsub un'espressione regolaree camminerà attraverso la stringa cercandocorrisponde a quel modello. Una delle sue caratteristiche interessanti è che possiamo dargli un hash e per ogni corrispondenza trovata esaminerà l'hash associato e restituirà il valore per le chiavi corrispondenti.

Ecco come creare facilmente un pattern che corrisponda alle chiavi nell'hash. Sto usando un pattern senza distinzione tra maiuscole e minuscole, ma YMMV:

key_regex = /b(?:#{ Regexp.union(replacement_hash.keys.map(&:to_s)).source })b/i # => /b(?:dog|cat)b/i

Nella sua forma più elementare, qui "è un gsub che utilizza un modello per cercare i valori in un hash:

string.gsub(key_regex, replacement_hash2) # => "The woof and meow"

È anche possibile cercare la stringa utilizzando un pattern, quindi passare gli "hit" a un blocco, che quindi calcola le sostituzioni necessarie:

string.gsub(key_regex) { |w| replacement_hash2[w] } # => "The woof and meow"

o:

string.gsub(key_regex) { |w| replacement_hash[w.to_sym] } # => "The woof and meow"

Ma aspetta! C'è più!

Se non vuoi l'approccio chirurgico, puoi anche utilizzare un modello regex più generico ("approccio a fucile") e gestire sia i colpi che i mancati quando guardi nell'hash:

string.gsub(/S+/) { |w| replacement_hash[w.to_sym] || "unknown" } # => "unknown woof unknown meow"

Questo trasforma il tuo codice originale in una singola, semplice, riga di codice. Modifica la regexp come necessario.

Medita su questo è il contenuto del blocco sopra non ha senso:

replacement_hash[:dog] # => "woof"
replacement_hash[:foo] # => nil
nil || "unknown" # => "unknown"

Si noti che è importante convertire la parola sospetta / target abbinata in un simbolo utilizzando il file replacement_hash hash. Ciò può diventare appiccicoso o contorto, perché alcune stringhe non si convertono in simboli in modo pulito e risultano in un simbolo con virgolette doppie. Dovresti tenerne conto nella tua definizione hash:

"foo".to_sym # => :foo
"foo_bar".to_sym # => :foo_bar
"foo-bar".to_sym # => :"foo-bar"
"foo bar".to_sym # => :"foo bar"