Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

337
Vistas
Ruby gsub para el número exacto de palabras

Tengo un fragmento de código donde puedo cambiar palabras de @post.swap_content a hipervínculos por palabra clave. Por ejemplo, tengo una palabra 'michigan' en @post.swap_content y tengo la palabra clave 'Michigan' en palabras clave, por lo que cambiaría al hipervínculo adjunto a la palabra clave. Aquí está parte de la función:

 def execute all_keys = Keyword.all.pluck(:key, :link).to_h.transform_keys(&:downcase) @post.swap_content = @post.swap_content.to_s.gsub!(/\w+/) do |word| url = all_keys[word.downcase] url ? "<a href='#{url}'>#{word}</a>" : word end @post.save! end

Y mi pregunta es: ¿cómo puedo hacer que gsub solo las dos primeras palabras clave en @post.swap_content? Por ejemplo, tengo @post.swap_content 'michigan, michigan y michigan, utah y utah', ¿cómo puedo cambiar a hipervínculos solo con las dos primeras palabras clave (las dos primeras 'michigan' y las dos primeras 'utah')? Creo que de alguna manera necesito trabajar con gsub, pero no sé cómo manejar la cantidad de palabras que pueden ser gsub.

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

Puede proporcionar un bloque a gsub que se invocará con cada coincidencia, puede usar esto para contar las ocurrencias y reemplazar el contenido de forma condicional.

 str = "Dog dog dog cat cat cat" occurences = {} str.gsub(/\w+/) do |match| # downcase so Dog and dog are counted together key = match.downcase # build a hash which counts the number of times we've matched a word. count = occurences.store(key, occurences.fetch(key, 0).next) # return the word unchanged or wrap in a hyperlink depending on count count > 2 ? match : "<a>#{match}</a>" end # output => "<a>Dog</a> <a>dog</a> dog <a>cat</a> <a>cat</a> cat"
over 4 years ago · Santiago Trujillo Denunciar

0

Suponer:

 str = "Dog dog cat dog cat Dog cat cat"

Si el motor de expresiones regulares de Ruby admitiera la búsqueda negativa de longitud variable, podríamos escribir:

 R = /\b(\w+)\b(?<!(?:\b\1\b.*){2})/i str.gsub(R, '<a>\1</a>') #=> "<a>Dog</a> <a>dog</a> <a>cat</a> dog <a>cat</a> Dog cat cat"

Podemos escribir esta expresión regular en modo de espacio libre para que sea autodocumentada:

 R = / \b # assert a word break (\w+) # match 1+ word characters and save to capture group 1 \b # assert a word break (?! # begin a negative lookbehind (?: # begin a non-capture group \b # assert a word break \1 # match the content of capture group 1 \b # assert a word break .* # match 0+ characters ) # end non-capture group {2} # execute non-capture group twice ) # end negative lookbehind /ix # assert case-independent and free-spacing regex def modes

Desafortunadamente, el motor de expresiones regulares de Ruby no admite búsquedas retrospectivas de longitud variable (positivas o negativas) (aunque algún día podría). Sin embargo, admite búsquedas anticipadas de longitud variable (positivas y negativas). Por lo tanto, podríamos invertir la cadena, realizar los reemplazos deseados usando gsub y luego invertir la cadena resultante, de la siguiente manera:

 R = /\b(\w+)\b(?!(?:.*\b\1\b){2})/i str.reverse.gsub(R, '>a/<\1>a<').reverse #=> "<a>Dog</a> <a>dog</a> <a>cat</a> dog <a>cat</a> Dog cat cat"

Los pasos son los siguientes.

 s = str.reverse #=> "tac tac goD tac god tac god goD" t = s.gsub(R, '>a/<\1>a<') #=> "tac tac goD >a/<tac>a< god >a/<tac>a< >a/<god>a< >a/<goD>a<" t.reverse #=> "<a>Dog</a> <a>dog</a> <a>cat</a> dog <a>cat</a> Dog cat cat"

Echemos un vistazo más de cerca a la expresión regular.

 R = / \b # assert a word break (\w+) # match 1+ word characters and save to capture group 1 \b # assert a word break (?! # begin a negative lookahead (?: # begin a non-capture group .* # match 0+ characters \b # assert a word break \1 # match the content of capture group 1 \b # assert a word break ) # end non-capture group {2} # execute non-capture group twice ) # end negative lookahead /ix # assert case-independent and free-spacing regex def modes
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda