可以将变量传递给regex文字然后将匹配组捕获到另一个局部变量吗?

时间:2015-10-07 16:02:27

标签: ruby regex

为了将regex capture groups保存到局部变量,正则表达式必须位于/(?<somegroup>someregex)/ =~ 'somestring'等操作的左侧。例如,给定url字符串,提取顶级域名:

/(?<extract>\b.com\b)[\/]{0,1}/ =~ 'google.com'
puts extract # => .com

有各种域名(.org,.scb,.wine,.me等)。我的策略是将all possible tlds from a reputable source存储在一个数组中,并遍历每个数组并将其传递给正则表达式。如何将变量传递给文字?

以下是我尝试做的简化方法:

def example_extract(url_str)
  exmpl = '.com'
  regx = /(?<extract>\b#{exmpl}\b)[\/]{0,1}/
  regx =~ url_str
  extract
end

example_extract('google.com')
# => NameError: undefined local variable or method `extract' for main:Object

我无法将变量传递给左手(文字)正则表达式操作。为什么我的捕获组extract未定义?

2 个答案:

答案 0 :(得分:1)

Regexp#=~的文档中,它说:

  

此分配在Ruby解析器中实现。解析器检测到赋值的'regexp-literal = ~expression'。正则表达式必须是文字而不插入并放在左侧。

未分配局部变量的原因是因为正则表达式是使用插值定义的,并且不是文字。

正如引文所暗示的那样,在解析阶段完成分配局部变量,并且由于字符串插值是在运行时完成的,因此似乎没有办法绕过规范所施加的限制。

答案 1 :(得分:0)

任何人未来的参考。你必须使用正则表达式的MatchData。这对我有用:

def example_extract(url_str)
  exmpl = '.com'
  regx = /(?<extract>\b#{exmpl}\b)[\/]{0,1}/
  extract = regx.match(url_str)[:extract]
  p extract
end

example_extract('google.com')