Chinaunix

标题: Perl 的范围操作符 [打印本页]

作者: perlearner    时间: 2011-12-09 16:44
标题: Perl 的范围操作符
请教各位老师,Perl的范围操作符 .. 在标量环境中具体是怎样执行的?

左操作数、右操作数和..操作符的布尔状态各是怎样转换的?

请高手通过代码把这个过程分解一下,万分感谢!
作者: ludio333    时间: 2011-12-09 17:15
大骆驼有介绍
作者: perlearner    时间: 2011-12-09 17:21
回复 2# ludio333


    在标量环境里,.. 返回一个布尔值。该操作符是双稳定的,类似一个电子开关,并且它仿真 sed,awk,和各种编辑器的行范围(逗号)操作符。每个 .. 操作符都维护自身的状态。只要它的左操作数为假就一直为假。一旦左操作数为真,该范围操作符就保持真的状态直到右操作数为真,右操作数为真之后该范围操作符再次为假。该操作符在下次计算之前不会变成假。它可以测试右操作数并且在右操作数变真后在同一次计算中变成假(awk 的范围操作符的特性),不过它还是会返回一次真。如果你不想拖到下一次计算中才测试右操作数(也是 sed 的范围操作符的工作方式),只需要用三个点(...)代替两个点(..)。对于 .. 和 ...,当操作符处于假状态后就不再测试右操作数,而当操作符处于真状态后就不再测试左操作数。

返回的值要么是代表假的空字串或者是代表真的一个序列数(从 1 开始)。该序列数每次碰到新范围时重置。在一个范围里的最后序列数后面附加了字串“E0”,这个字串不影响它的数字值,只是给你一些东西让你可以搜索,这样你可以把终点排除在外。你也可以通过等待 1 的序列数的方法把启始点排除在外。如果标量 .. 的某个操作数是数字文本,那么该操作数隐含地与 $.变量对比,$. 里包含你的输入文件的当前行号。

原书中是这样讲的,小弟初学,请您详细讲解一下好吗?谢谢了~
作者: zhlong8    时间: 2011-12-11 19:44
回复  ludio333


    在标量环境里,.. 返回一个布尔值。该操作符是双稳定的,类似一个电子开关,并且 ...
perlearner 发表于 2011-12-09 17:21



    这个帖子 http://bbs.chinaunix.net/thread-3620429-1-2.html
作者: perlearner    时间: 2011-12-14 12:13
本帖最后由 perlearner 于 2011-12-14 13:50 编辑

回复 4# zhlong8


    非常感谢,还有一点疑问,请您指点一下

如下代码

foreach my $x ( 1..10 ){print $x if $x == 3..$x >= 3}     # 只打印 3
foreach my $x ( 1..10 ){print $x if $x == 3...$x >= 3}    #打印 3 和 4

按照大骆驼中的规则解释第一行代码:1、在1..10的范围内,$x被反复赋值,整个表达式的初始布尔状态为假,并且当$x值为1和2时一直为假
                                  2、以3为临界点,当$x的值为3时,布尔状态切换为true并返回true,一直保持true的状态,同时继续测试右操作数
                                  3、当$x的值为4时,布尔状态切换为false,且在$x>3时一直为false
                                                        整个表达式只有在$x的值为3时为true,所以最后只打印3
按照上面的方式和过程理解正确吗?

如果正确的话那么,

问题1:>=表示大于或者等于,但是为什么当$x的值为4 5 6 7 的时候布尔值为假呢?

问题2:两点..范围操作符和三点...范围操作符有什么区别,书上面说“它等到下一次求值的时候才测试其右侧表达式”,这句话应该怎样理解?

问题3:foreach my $x ( 1..10 ){print $x if $x == 3...$x <= 3} 执行的结果为打印 3 4 5 6 7 8 9 10,更加困惑,求解!

跪求高手指点小弟一下,谢谢!
作者: yybmsrs    时间: 2011-12-14 14:42
中文看不懂就看英文:
     In scalar context, ".." returns a boolean value.  The
     operator is bistable, like a flip-flop, and emulates the
     line-range (comma) operator of sed, awk, and various
     editors.  Each ".." operator maintains its own boolean
     state.  It is false as long as its left operand is false.
     Once the left operand is true, the range operator stays true
     until the right operand is true, AFTER which the range
     operator becomes false again.  It doesn't become false till
     the next time the range operator is evaluated.  It can test
     the right operand and become false on the same evaluation it
     became true (as in awk), but it still returns true once.  If
     you don't want it to test the right operand till the next
     evaluation, as in sed, just use three dots ("...") instead
     of two.  In all other regards, "..." behaves just like ".."
     does.

作者: perlearner    时间: 2011-12-14 14:50
回复 6# yybmsrs


    感谢楼上,我看过英文,不过还是对..的规则有些费解,请您点播一下,谢谢~
作者: yybmsrs    时间: 2011-12-14 15:06
回复 7# perlearner


   
foreach my $x ( 1..10 ){print $x if $x == 3..$x >= 3}     # 只打印 3
$x为3的时候判断一下前面的为真,整个操作符就为真,继续判断后面的也为真,AFTER 然后3之后操作符就为假,所以4就是假了

foreach my $x ( 1..10 ){print $x if $x == 3...$x >= 3}    #打印 3 和 4

$x为3的时候判断一下前面的为真,整个操作符就为真,但是到下一个$x也就是4才判断后面的条件,于是到4的时候判断后面为真,AFTER 整个操作符为假,所以4之后的就是假,3和4为真

多看几遍就明白了
作者: perlearner    时间: 2011-12-14 16:27
回复 8# yybmsrs


    多谢yybmsrs 的详细指点,问题解决!
作者: jingxi258    时间: 2011-12-22 12:07
yybmsrs 发表于 2011-12-14 15:06
回复 7# perlearner

我怎么觉得你说反了,手册上不是说 ... 不会拖到下一次计算才测试右操作数么,.. 才会拖到下一次计算才测试右操作数。




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2