免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5704 | 回复: 9
打印 上一主题 下一主题

Perl 的范围操作符 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-12-09 16:44 |只看该作者 |倒序浏览
请教各位老师,Perl的范围操作符 .. 在标量环境中具体是怎样执行的?

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

请高手通过代码把这个过程分解一下,万分感谢!

论坛徽章:
0
2 [报告]
发表于 2011-12-09 17:15 |只看该作者
大骆驼有介绍

论坛徽章:
0
3 [报告]
发表于 2011-12-09 17:21 |只看该作者
回复 2# ludio333


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

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

原书中是这样讲的,小弟初学,请您详细讲解一下好吗?谢谢了~

论坛徽章:
46
15-16赛季CBA联赛之四川
日期:2018-03-27 11:59:132015年亚洲杯之沙特阿拉伯
日期:2015-04-11 17:31:45天蝎座
日期:2015-03-25 16:56:49双鱼座
日期:2015-03-25 16:56:30摩羯座
日期:2015-03-25 16:56:09巳蛇
日期:2015-03-25 16:55:30卯兔
日期:2015-03-25 16:54:29子鼠
日期:2015-03-25 16:53:59申猴
日期:2015-03-25 16:53:29寅虎
日期:2015-03-25 16:52:29羊年新春福章
日期:2015-03-25 16:51:212015亚冠之布里斯班狮吼
日期:2015-07-13 10:44:56
4 [报告]
发表于 2011-12-11 19:44 |只看该作者
回复  ludio333


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



    这个帖子 http://bbs.chinaunix.net/thread-3620429-1-2.html

论坛徽章:
0
5 [报告]
发表于 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,更加困惑,求解!

跪求高手指点小弟一下,谢谢!

论坛徽章:
78
双子座
日期:2013-10-15 08:50:09天秤座
日期:2013-10-16 18:02:08白羊座
日期:2013-10-18 13:35:33天蝎座
日期:2013-10-18 13:37:06狮子座
日期:2013-10-18 13:40:31双子座
日期:2013-10-22 13:58:42戌狗
日期:2013-10-22 18:50:04CU十二周年纪念徽章
日期:2013-10-24 15:41:34巨蟹座
日期:2013-10-24 17:14:56处女座
日期:2013-10-24 17:15:30双子座
日期:2013-10-25 13:49:39午马
日期:2013-10-28 15:02:15
6 [报告]
发表于 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.

论坛徽章:
0
7 [报告]
发表于 2011-12-14 14:50 |只看该作者
回复 6# yybmsrs


    感谢楼上,我看过英文,不过还是对..的规则有些费解,请您点播一下,谢谢~

论坛徽章:
78
双子座
日期:2013-10-15 08:50:09天秤座
日期:2013-10-16 18:02:08白羊座
日期:2013-10-18 13:35:33天蝎座
日期:2013-10-18 13:37:06狮子座
日期:2013-10-18 13:40:31双子座
日期:2013-10-22 13:58:42戌狗
日期:2013-10-22 18:50:04CU十二周年纪念徽章
日期:2013-10-24 15:41:34巨蟹座
日期:2013-10-24 17:14:56处女座
日期:2013-10-24 17:15:30双子座
日期:2013-10-25 13:49:39午马
日期:2013-10-28 15:02:15
8 [报告]
发表于 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为真

多看几遍就明白了

论坛徽章:
0
9 [报告]
发表于 2011-12-14 16:27 |只看该作者
回复 8# yybmsrs


    多谢yybmsrs 的详细指点,问题解决!

论坛徽章:
0
10 [报告]
发表于 2011-12-22 12:07 |只看该作者
yybmsrs 发表于 2011-12-14 15:06
回复 7# perlearner

我怎么觉得你说反了,手册上不是说 ... 不会拖到下一次计算才测试右操作数么,.. 才会拖到下一次计算才测试右操作数。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP