简体   繁体   English

Ruby(Rails)gsub:将捕获的字符串传递给方法

[英]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. 我的问题是当我在我用gsub调用的embed_hashtag方法中传递'\\1'时,它只是简单地传递"\\1" ,而不是我的正则表达式中的第一个捕获组。 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 (ie hashtags) which needs to be passed raw (hence raw ). 我在h包装文本以转义字符串,但后来我将代码嵌入到用户输入的文本(即主题标签)中,这些文本需要原始传递(因此是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. 如果你有更好的方法做到这一点,请不要犹豫让我知道,但为了回答这个问题,我仍然想要一个答案,以防其他人有这个问题。

  • Use the block form gsub(regex){ $1 } instead of gsub(regex, '\\1') 使用块格式gsub(regex){ $1 }而不是gsub(regex, '\\1')
  • You can simplify the regex to /\\B#(\\w+)/i as well 您也可以将正则表达式简化为/\\B#(\\w+)/i
  • You can leave out the h() helper, Rails 4 will escape malicious input by default 你可以省略h()帮助器,Rails 4默认会逃避恶意输入
  • Specify method arguments as embed_hashtag(data) instead of embed_hashtag('data') 将方法参数指定为embed_hashtag(data)而不是embed_hashtag('data')
  • You need to define embed_hashtag before doing the substitution 您需要在执行替换之前定义embed_hashtag
  • To build a link, you can use link_to(text, url) 要构建链接,可以使用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) }
)

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) }
)

Try last match regexp shortcut: 尝试最后一次匹配正则表达式快捷方式:

=> 'zzzdzz'.gsub(/d/) { puts $~[0] }
=> 'd'
=> "zzzzz"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM