为了将正则表达式捕获组保存到一个局部变量中,正则表达式必须位于操作(如/(?<somegroup>someregex)/ =~ 'somestring'
)的左侧。例如,给定一个url字符串,提取顶级域:
/(?<extract>b.comb)[/]{0,1}/ =~ 'google.com'
puts extract # => .com
有各种各样的域名(.org, .scb, .wine, .me等)。我的策略是将来自可靠源的所有可能的tld存储在一个数组中,并遍历每个tld并将其传递给正则表达式。如何将变量传递给文本?
下面是我要做的事情的一个简化方法:
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
没有定义?
在Regexp#=~的文档中,它说:
这个赋值在Ruby解析器中实现。解析器为赋值检测' regexp-literal =~ expression '。regexp必须是不带插值且位于左侧的字面值。
局部变量没有赋值的原因是你的正则表达式是用插值定义的,而不是一个文字。
正如引文所暗示的那样,局部变量的赋值是在解析阶段完成的,由于字符串插值是在运行时完成的,因此似乎没有办法绕过规范施加的限制。
供大家参考。你必须使用regexp的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')