如何评估孤立的正则表达式

时间:2014-03-08 14:59:31

标签: ruby regex

我到处都看到这个片段,它有效!为什么呢?

while gets
    print if /start/../end/
end

如果没有Lvalue,ruby如何评估/start/?我希望我们首先必须在某处存储'gets'的值,然后再进行

gets_result =~ /start/.. gets_result =~ /end/

那么为什么代码片段有效?

让我澄清一下。

ruby​​如何知道比较正则表达式与获取在上面的代码段中,我没有指定ruby将reg exp与gets进行比较但它只是知道。问题是怎么样的?

3 个答案:

答案 0 :(得分:4)

Kernel#gets不仅会返回下一行,还会将值指定给$_

如果没有争论,

Kernel#print打印$_

触发器操作符(/start/../end/)也在$_上运行。

答案 1 :(得分:2)

好问题。

请记住:条件语句中使用Range运算符(.....)时,它会执行某些操作完全出乎意料:它没有创建一个Range对象。相反,它充当“触发器”运算符。

下面的代码实际上是

while gets
    print if /start/../end/
end

默认为

while gets
    # gets_input I put just to make the code more expressive
    # actually the input taken using gets method applied here implicitly.
    print if  /start/ =~ gets_input .. /end/ =~ gets_input
end

让我来证明你。我接受了Ruby Tracer类的帮助。

trace = TracePoint.new do |tp|
  p [tp.lineno, tp.event, tp.defined_class,tp.method_id]
end
trace.enable do
  while gets
    # when you type start in your console, 11 will be output.
    print 11 if /start/../end/
  end
end

让我运行此代码,向您展示我的上述代码作为证明以及Ruby Flip-Flop 功能:

(arup~>Ruby)$ ruby test.rb
test.rb:6: warning: regex literal in condition
test.rb:6: warning: regex literal in condition
[4, :b_call, nil, nil]
[5, :line, nil, nil]
[5, :c_call, Kernel, :gets]
[5, :c_call, ARGF.class, :gets]
end # I presses **end** here.
[5, :c_return, ARGF.class, :gets]
[5, :c_return, Kernel, :gets]
[6, :line, nil, nil]
# Regexp#=~ call begin happened for /end/ =~ gets_input
[6, :c_call, Regexp, :=~]
# Regexp#=~ call end happened for /end/ =~ gets_input
[6, :c_return, Regexp, :=~] 
[5, :c_call, Kernel, :gets]
[5, :c_call, ARGF.class, :gets]
start # I presses **start** here.
[5, :c_return, ARGF.class, :gets]
[5, :c_return, Kernel, :gets]
[6, :line, nil, nil]
# Regexp#=~ call begin happened for /start/ =~ gets_input
[6, :c_call, Regexp, :=~] 
# Regexp#=~ call end happened for /start/ =~ gets_input
[6, :c_return, Regexp, :=~]
# Regexp#=~ call begin happened for /end/ =~ gets_input
[6, :c_call, Regexp, :=~] 
# Regexp#=~ call end happened for /end/ =~ gets_input
[6, :c_return, Regexp, :=~] 
[6, :c_call, Kernel, :print]
[6, :c_call, IO, :write]
[6, :c_call, Fixnum, :to_s]
[6, :c_return, Fixnum, :to_s]
# As there is a match so **if** clause true, thus 11 printed
11[6, :c_return, IO, :write] 
[6, :c_return, Kernel, :print]
[5, :c_call, Kernel, :gets]
[5, :c_call, ARGF.class, :gets]
end  
[5, :c_return, ARGF.class, :gets]
[5, :c_return, Kernel, :gets]
[6, :line, nil, nil]
[6, :c_call, Regexp, :=~]
[6, :c_return, Regexp, :=~]
[6, :c_call, Kernel, :print]
[6, :c_call, IO, :write]
[6, :c_call, Fixnum, :to_s]
[6, :c_return, Fixnum, :to_s]
11[6, :c_return, IO, :write]
[6, :c_return, Kernel, :print]
[5, :c_call, Kernel, :gets]
[5, :c_call, ARGF.class, :gets]

答案 2 :(得分:0)

在这种情况下,..是触发器操作符。给定'start'时,条件的计算结果为true,并继续true直到end为止。