免费注册 查看新帖 |

Chinaunix

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

当grep碰到encode,乱了套了,求解答 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-01-09 15:06 |只看该作者 |倒序浏览
想问的就是grep和map的区别,网上学了不少,知道grep是判别如果list符合条件就取出来;map是整个list都处理过来,特别是仙子05年的文章,好详细~

也学习到其实Block如果不是判断,grep也可以用,就会把list所有元素都按照Block跑一边输出

所以能测试的都测了一遍没什么问题,唯独这个encode和decode,非常奇怪。
  1. #!perls -w
  2. #short test

  3. use 5.012;
  4. use utf8;
  5. use autodie;
  6. use Encode;

  7. my @foos = qw /alt aol ate aaa acf atl 好天气/;
  8. say "@foos\n" . '-'x 10 . "\n";
  9. my @foos2 = grep encode('gbk', $_), @foos;
  10. say "@foos";
  11. say "@foos2";

  12. #my @foos = qw /alt aol ate aaa acf atl/;
  13. #my @foos2 = grep {$_ = 'a'} @foos;
  14. #say @foos;
  15. #say @foos2;
  16. <>;
复制代码
问题集中在11行,

1、如果grep换成map,一切正常;
2、用grep的话,下面12,13行@foos和@foos2都是原样保持不变;
        2-a、11行grep里面“违规”使用了$_,但是最后@foos依然没有被改变,说明实际没有处理@foos??
        2-b、但是@foos2变成了@foos的值,说明什么?如果grep没有工作的话,@foos2怎么会赋值,如果grep工作的话,怎么@foos2的最后一个中文还是乱码?明显没有encode啊

运行结果
  1. E:\word处理\testdir>mono.pl
  2. Wide character in say at E:\word处理\testdir\mono.pl line 10.
  3. alt aol ate aaa acf atl 濂藉ぉ姘?
  4. ----------

  5. Wide character in say at E:\word处理\testdir\mono.pl line 12.
  6. alt aol ate aaa acf atl 濂藉ぉ姘?
  7. Wide character in say at E:\word处理\testdir\mono.pl line 13.
  8. alt aol ate aaa acf atl 濂藉ぉ姘?
复制代码
如果grep换成map
  1. E:\word处理\testdir>mono.pl
  2. Wide character in say at E:\word处理\testdir\mono.pl line 10.
  3. alt aol ate aaa acf atl 濂藉ぉ姘?
  4. ----------

  5. Wide character in say at E:\word处理\testdir\mono.pl line 12.
  6. alt aol ate aaa acf atl 濂藉ぉ姘?
  7. alt aol ate aaa acf atl 好天气
复制代码
求解答~

论坛徽章:
0
2 [报告]
发表于 2015-01-09 15:09 |只看该作者
最后部分,当grep换成map

由输出第7行发现,@foos还是没变
说明encode可以保护$_不被更改?

求职 : Linux运维
论坛徽章:
3
戌狗
日期:2015-01-11 13:27:532015年辞旧岁徽章
日期:2015-03-03 16:54:152015年亚洲杯纪念徽章
日期:2015-05-08 15:03:30
3 [报告]
发表于 2015-01-10 07:41 |只看该作者
grep后接判断代码块才能实现筛选。
你后面只有encode,则默认代码块判断全为真,foos全部赋值给foos2,grep对foos无任何改变。

至于改成map,foos仍无变化,同理。
而foos2是对每一个foos的元素做encode后得到,所以foos2能正确。

论坛徽章:
0
4 [报告]
发表于 2015-01-11 00:02 |只看该作者
貌似有点问题啊

grep时,只有encode,则默认代码块判断全为真 => 应该执行这个encode啊,然后$foos2存的是encode过的foos,不该是乱码

另外,语句grep encode('gbk', $_), @foos;明显已经改动了$_,也就是foos被改动了,可是在程序第12行say foos;输出依然是乱码(见grep或者是map,输出的第7行)

求教~

回复 3# donalds2008


   

论坛徽章:
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
5 [报告]
发表于 2015-01-11 10:10 |只看该作者
encode 就是个普通的函数,没副作用。所以这里不改变 $_,写成 $_ = encode('gbk', $_) 还差不多

求职 : Linux运维
论坛徽章:
3
戌狗
日期:2015-01-11 13:27:532015年辞旧岁徽章
日期:2015-03-03 16:54:152015年亚洲杯纪念徽章
日期:2015-05-08 15:03:30
6 [报告]
发表于 2015-01-11 13:21 |只看该作者
回复 4# 死水站


    你看看没encode之前的foos就是乱码。
    1、用grep只是取出foos的每一个值进行encode计算,并没返回结果给foos,则未改变foos
   2、 因为grep里只有encode,则对每一个取出值做encode,若encode结果非0(即为真),则取该值加入foos2。据此,由于foos中值encode后均为真,则foos中所有元素都给foos2。所以,encode后的foo和foos2,与之前的foos一样。
   

论坛徽章:
0
7 [报告]
发表于 2015-01-11 15:21 |只看该作者
@donalds2008
@zhlong8

第1个确实是脑子抽了,encode过的@foos根本没有赋值给任何数,哈哈。

第2个,我想我是明白了吧,总结一下是这样(当然刚才又去把仙子姐姐05年的博文翻了翻):

@As = grep EXPR/BLOCK, LIST; 是把LIST里的值(a1,a2,a3……)依次放入EXPR/BLOCK运算,结果为真的an放入@As中,这过程中EXPR/BLOCK如果有输出,替换或者赋值(比如say; s///;),原先的变量才会改变;

@Bs = map  EXPR/BLOCK, LIST; 将LIST中的值(b1,b2,b3……)依次做EXPR/BLOCK运算并放入@Bs,执行之后@Bs中放的是运算过的b1,b2,b3……

由此可见grep和map从本质上说是作用完全不同的两个函数:
grep是判断筛选,(“仅有一个没有左值的表达式时”)不改变目标变量;
map类似于foreach,就是将目标变量依次放入表达式执行,输出结果。

唯一相同点是两个函数都有遍历过程。


总结的对吗? 对的话就放这儿留给后续新人学习~~
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP