【问题标题】:Ruby (Rails) gsub: pass the captured string into a methodRuby(Rails)gsub:将捕获的字符串传递给方法
【发布时间】:2014-06-15 15:00:23
【问题描述】:

我正在尝试匹配这样的字符串:

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

我的问题是,当我在使用 gsub 调用的 embed_hashtag 方法中传递 '\1' 时,它只是从字面上传递 "\1",而不是从我的正则表达式中捕获的第一个组。有其他选择吗?

仅供参考:

  1. 我将文本包装在 h 中以转义字符串,但随后我将代码嵌入到需要原始传递的用户输入文本(即主题标签)中(因此 raw)。

  2. 将“#”符号与文本分开很重要,这就是我认为我需要捕获组的原因。

  3. 如果您有更好的方法,请随时告诉我,但我仍然希望得到答案,以防其他人有此问题。

【问题讨论】:

  • 你需要使用#gsubblock版本..不是你正在使用的那个..这个discussion会帮助你理解这一点。

标签: ruby-on-rails ruby regex gsub ruby-on-rails-4.1


【解决方案1】:
  • 使用块形式gsub(regex){ $1 } 而不是gsub(regex, '\1')
  • 您也可以将正则表达式简化为 /\B#(\w+)/i
  • 您可以省略 h() 帮助程序,Rails 4 默认会避开恶意输入
  • 将方法参数指定为embed_hashtag(data) 而不是embed_hashtag('data')
  • 你需要在替换之前定义embed_hashtag
  • 要建立链接,您可以使用link_to(text, url)

这应该可以解决问题:

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

raw(
  text.gsub(/\B#(\w+)/i){ embed_hashtag($1) }
)

【讨论】:

  • 对于替代形式,embed_hashtag 必须接收 x[1] 作为参数。
  • @CasimiretHippolyte 对不起,你(几乎)是对的。第二种形式不起作用,但你的也不起作用,因为它的意思是“整个匹配的第一个字符”。所以唯一的解决办法是使用$1
  • 并且没有办法将第一个捕获组传递给函数?
  • 是的,有——这是我发布的解决方案。 $& 包含整个最后一场比赛; $1 ... $9 包含最后一场比赛的捕获组 1 ... 9; $~ 包含 MatchData 对象,等效于 Regexp.last_match。参考文档:ruby-doc.org/core-2.1.1/String.html#method-i-gsub
【解决方案2】:

正确的方法是在这里使用块。

示例

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

text = 'This is a #hashtag'
raw(
 h(text).gsub(/\B#(\S+)/) { embed_hashtag($1) }
)

【讨论】:

    【解决方案3】:

    尝试最后一次匹配正则表达式快捷方式:

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

    【讨论】:

      猜你喜欢
      • 2012-12-21
      • 1970-01-01
      • 2014-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-22
      • 2012-10-11
      • 2013-03-31
      相关资源
      最近更新 更多