/ / Come `gsub` differisce da` gsub! `Quando si usa la chiave hash come pattern per sostituire i suoi valori? [chiuso] - rubino, regex, hash

In che modo `gsub` differisce da` gsub! `Quando si usa la chiave hash come pattern per sostituire i suoi valori? [chiuso] - rubino, regex, hash

ero solito gsub! per sostituire una corrispondenza con una chiave hash con il suo valore hash. Per esempio:

def replace_string(string = "@ReplaceMe[xyz]@@ReplaceMe[123]@Hello")
generator_replacements = {
"@ReplaceMe[xyz]@" => "Time",
"@ReplaceMe[123]@" => "Date"
}
generator_replacements.each{
|generator, replacement|
string = string.gsub!(generator.to_s, replacement.to_s)
puts string
}
end

replace_string

uscite:

  1. TimeDateHello
  2. TimeDateHello

Non capisco perché gsub! ha sostituito tutte le chiavi hash in una volta sola piuttosto che ad ogni iterazione. Quando provo ad usare gsub, sostituisce con ogni iterazione:

  1. Time@ReplaceMe[123]@Hello
  2. TimeDateHello

Qualcuno può spiegare perché questo accade?

risposte:

1 per risposta № 1

Non c'è differenza in questo senso. Il each il ciclo viene eseguito elemento per elemento e nessuno dei due gsubgsub! può prevedere il futuro.

Questo codice:

replacements = { "foo" => "hello", "bar" => "world" }
string = "foo bar!"
replacements.each do |placeholder, value|
string = string.gsub(placeholder, value)
end
string #=> "hello world!"

è equivalente a:

string = "foo bar!"
string = string.gsub("foo", "hello") #=> "hello bar!"
string = string.gsub("bar", "world") #=> "hello world!"
string #=> "hello world!"

con gsub! potresti scrivere:

string = "foo bar!"
string.gsub!("foo", "hello") #=> "hello bar!"
string.gsub!("bar", "world") #=> "hello world!"
string #=> "hello world!"

La differenza principale è questa gsub! cambia il ricevitore sul posto, mentre gsub restituisce una nuova stringa (da qui la necessità di assegnarla a string).

Per eseguire più sostituzioni contemporaneamente, puoi passare un hash a gsub:

string = "foo bar!"
string.gsub(/foo|bar/, { "foo" => "hello", "bar" => "world" })
#=> "hello world!"

L'espressione regolare può anche essere generata a livello di codice:

replacements = { "foo" => "hello", "bar" => "world" }
string = "foo bar!"
string.gsub(Regexp.union(replacements.keys), replacements)
#=> "hello world!"

0 per risposta № 2

Ho modificato il tuo codice in modo che funzioni come mostrato di seguito:

def replace_string(generated_string = "@ReplaceMe[xyz]@@ReplaceMe[123]@Hello")
generator_replacements = {
"@ReplaceMe[xyz]@" => "Time",
"@ReplaceMe[123]@" => "Date"
}
generator_replacements.each do |generator, replacement|
string = generated_string.gsub(generator.to_s, replacement.to_s)
puts string
end
end

Con questo codice usando gsub Ottengo:

Time@ReplaceMe[123]@Hello
@ReplaceMe[xyz]@DateHello

e con gsub! Ottengo:

Time@ReplaceMe[123]@Hello
TimeDateHello

La ragione di questo è quello gsub! modifica la stringa esistente dove gsub non modifica la stringa esistente. Questo aiuta a rispondere alla tua domanda?