Tengo un montón de frases a las que les faltan apóstrofes, y tengo una variedad de correcciones como esta:
phrase = "id let some" def contractions_to_fix [ { missing: "let s", fixed: "let's" }, { missing: "i d", fixed: "i'd" } ] endEstoy tratando de recorrer la serie de contracciones para reemplazarlas, así:
contractions_to_fix.each do |contraction| if phrase.include? contraction[:missing] idea_title.gsub! contraction[:missing], contraction[:fixed] end end El objetivo, para este ejemplo, sería devolver "i'd let some" ; sin embargo, cada expresión regular que he probado hasta ahora devuelve una respuesta incorrecta.
Por ejemplo:
contraction[:missing] da como resultado "i'd let'some/\bcontraction[:missing]\b/ da como resultado "id let some"¡Cualquier ayuda sería muy apreciada!
La forma más fácil de codificar el requisito exacto en su título es cambiar su condición: "no está precedido ni seguido por un espacio":
idea_title.gsub!(/(?<!\S)#{Regexp.escape(contraction[:missing])}(?!\S)/, contraction[:fixed]) Aunque /\b#{...}\b/ debería funcionar para el ejemplo que diste. ¡Su problema es probablemente el hecho de que alimenta una String como patrón en gsub! en lugar de Regexp , por lo que literalmente está buscando \b (barra invertida y B minúscula), no un límite de palabra. Pruébalo con
idea_title.gsub!(/\b#{Regexp.escape(contraction[:missing])}\b/, contraction[:fixed])arr = [ { missing: "let s", fixed: "let's" }, { missing: "i d", fixed: "i'd" } ] h = arr.reduce({}) { |h,g| h.merge(g[:missing]=>g[:fixed]) } #=> {"let s"=>"let's", "i d"=>"i'd"} r = /\b(?:#{h.keys.join('|')})\b/ #=> /\b(?:let s|id)\b/ "id want to let some".gsub(r, h) #=> "i'd want to let some"Esto usa la (segunda) forma de String.gsub que toma un hash como segundo argumento y no tiene bloque.
Alternativamente, se puede calcular h de la siguiente manera.
h = arr.map { |g| g.values_at(:missing, :fixed) }.to_h #=> {"let s"=>"let's", "i d"=>"i'd"}