Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby (Rails) gsub: pass the captured string into a method

I'm trying to match a string as such:

text = "This is a #hastag"
raw(
  h(text).gsub(/(?:\B#)(\w*[A-Z]+\w*)/i, embed_hashtag('\1'))
)

def embed_hashtag('data')
  #... some code to turn the captured hashtag string into a link
  #... return the variable that includes the final string
end

My problem is that when I pass '\1' in my embed_hashtag method that I call with gsub, it simply passes "\1" literally, rather than the first captured group from my regex. Is there an alternative?

FYI:

  1. I'm wrapping text in h to escape strings, but then I'm embedding code into user inputted text (i.e. hashtags) which needs to be passed raw (hence raw).

  2. It's important to keep the "#" symbol apart from the text, which is why I believe I need the capture group.

  3. If you have a better way of doing this, don't hesitate to let me know, but I'd still like an answer for the sake of answering the question in case someone else has this question.

like image 503
user2985898 Avatar asked Dec 21 '25 01:12

user2985898


2 Answers

  • Use the block form gsub(regex){ $1 } instead of gsub(regex, '\1')
  • You can simplify the regex to /\B#(\w+)/i as well
  • You can leave out the h() helper, Rails 4 will escape malicious input by default
  • Specify method arguments as embed_hashtag(data) instead of embed_hashtag('data')
  • You need to define embed_hashtag before doing the substitution
  • To build a link, you can use link_to(text, url)

This should do the trick:

def embed_hashtag(tag)
  url = 'http://example.com'
  link_to tag, url
end

raw(
  text.gsub(/\B#(\w+)/i){ embed_hashtag($1) }
)
like image 67
Patrick Oscity Avatar answered Dec 22 '25 16:12

Patrick Oscity


The correct way would be the use of a block here.

Example:

def embed_hashtag(data)
  puts "#{data}"
end

text = 'This is a #hashtag'
raw(
 h(text).gsub(/\B#(\S+)/) { embed_hashtag($1) }
)
like image 33
hwnd Avatar answered Dec 22 '25 17:12

hwnd



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!