Har*_*ina 21 ruby regex metaprogramming
这是Ruby 1.8.7但应该与1.9.x相同
我试图拆分一个字符串,例如:
a = "foo.bar.size.split('.').last"
# trying to split into ["foo", "bar","split('.')","last"]
Run Code Online (Sandbox Code Playgroud)
基本上在它代表的命令中拆分它,我试图用Regexp做但不确定如何,想法是使用regexp
a.split(/[a-z\(\)](\.)[a-z\(\)]/)
Run Code Online (Sandbox Code Playgroud)
在这里尝试使用组(\.)
来分割它,但这似乎不是一个好方法.
Jas*_*ett 31
我认为这样做会:
a.split(/\.(?=[\w])/)
Run Code Online (Sandbox Code Playgroud)
我不知道你对正则表达式了解多少,但这(?=[\w])
是一个前瞻性的说法,"如果下一个字符是一个字母的字符,则只匹配点".预测实际上不会抓取它匹配的文本.它只是"看起来".所以结果正是你想要的:
> a.split(/\.(?=[\w])/)
=> ["foo", "bar", "size", "split('.')", "last"]
Run Code Online (Sandbox Code Playgroud)
我担心正则表达式不会带你走得太远.考虑以下表达式(也是有效的Ruby)
"(foo.bar.size.split( '.' )).last"
"(foo.bar.size.split '.').last"
"(foo.bar.size.split '( . ) . .(). .').last"
Run Code Online (Sandbox Code Playgroud)
问题是,调用列表实际上是一个调用树.最简单的解决方案可能是使用Ruby解析器并根据您的需要转换解析树(在此示例中,我们递归地下降到调用树中,将调用收集到列表中):
# gem install ruby_parser
# gem install awesome_print
require 'ruby_parser'
require 'ap'
def calls_as_list code
tree = RubyParser.new.parse(code)
t = tree
calls = []
while t
# gather arguments if present
args = nil
if t[3][0] == :arglist
args = t[3][1..-1].to_a
end
# append all information to our list
calls << [t[2].to_s, args]
# descend to next call
t = t[1]
end
calls.reverse
end
p calls_as_list "foo.bar.size.split('.').last"
#=> [["foo", []], ["bar", []], ["size", []], ["split", [[:str, "."]]], ["last", []]]
p calls_as_list "puts 3, 4"
#=> [["puts", [[:lit, 3], [:lit, 4]]]]
Run Code Online (Sandbox Code Playgroud)
并显示任何输入的解析树:
ap RubyParser.new.parse("puts 3, 4")
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
32727 次 |
最近记录: |