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