免费注册 查看新帖 |

Chinaunix

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

已经解决.结贴 脚本 Perl - 如何理解 split 函数的返回值 [复制链接]

论坛徽章:
307
程序设计版块每周发帖之星
日期:2016-04-08 00:41:33操作系统版块每日发帖之星
日期:2015-09-02 06:20:00每日论坛发贴之星
日期:2015-09-02 06:20:00程序设计版块每日发帖之星
日期:2015-09-04 06:20:00每日论坛发贴之星
日期:2015-09-04 06:20:00每周论坛发贴之星
日期:2015-09-06 22:22:00程序设计版块每日发帖之星
日期:2015-09-09 06:20:00程序设计版块每日发帖之星
日期:2015-09-19 06:20:00程序设计版块每日发帖之星
日期:2015-09-20 06:20:00每日论坛发贴之星
日期:2015-09-20 06:20:00程序设计版块每日发帖之星
日期:2015-09-22 06:20:00程序设计版块每日发帖之星
日期:2015-09-24 06:20:00
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-10-12 10:39 |只看该作者 |倒序浏览
本帖最后由 sunzhiguolu 于 2015-10-12 23:25 编辑

我有一个文本文件, 内容如下:

  1. ZhangSan m 15600000000
  2. LiNa f
复制代码
我测试代码如下:

  1. #!/usr/bin/perl
  2. use 5.010;
  3. use strict;
  4. use warnings;

  5. while (<>){
  6.     my ($name, $gender, $phone_number) = split /\s+/;
  7.     say "\$name=$name,\$gender=$gender,\$phone_number=$phone_number" if ($phone_number eq "");
  8.     #my @a_line = split /\s+/;
  9.     #printf "%d.>%d\n", $., scalar (@a_line);
  10. }
复制代码
以上代码, 我有些地方不明白向大家请教, 请大家给予帮助及支持, 先谢过大家了...
1.> 通过 split 以空白字符将一行文本分割后, 为何文本中 LiNa 的哪一行的
    $phone_number 变量的值不是 undef 而是 "空串"?

论坛徽章:
307
程序设计版块每周发帖之星
日期:2016-04-08 00:41:33操作系统版块每日发帖之星
日期:2015-09-02 06:20:00每日论坛发贴之星
日期:2015-09-02 06:20:00程序设计版块每日发帖之星
日期:2015-09-04 06:20:00每日论坛发贴之星
日期:2015-09-04 06:20:00每周论坛发贴之星
日期:2015-09-06 22:22:00程序设计版块每日发帖之星
日期:2015-09-09 06:20:00程序设计版块每日发帖之星
日期:2015-09-19 06:20:00程序设计版块每日发帖之星
日期:2015-09-20 06:20:00每日论坛发贴之星
日期:2015-09-20 06:20:00程序设计版块每日发帖之星
日期:2015-09-22 06:20:00程序设计版块每日发帖之星
日期:2015-09-24 06:20:00
2 [报告]
发表于 2015-10-12 11:13 |只看该作者
本帖最后由 sunzhiguolu 于 2015-10-12 11:22 编辑

我先说下我疑惑的地方:
1.> split 函数将文本行末尾的换行符也匹配到了, 然后将包含 LiNa 的哪一行
    分割成包含三个元素的列表返回;
    1.1> 但是如果将代码中的第 9, 10 行的注释去掉, 发现实际分割后得到的数组的元素个数却是 2 ;
    1.2> 那么将一个包含两个元素的列表或数组向包含三个元素的列表赋值的话, 最后一个元素的值
         不应该是 undef 吗?
-------------------------------------------------------------------------------------------------
下面是我的测试代码:

  1. #!/usr/bin/perl
  2. use 5.010;
  3. use strict;
  4. use warnings;

  5. my @a_numbers = (1,2);
  6. my ($one, $two, $three) = (@a_numbers);
  7. say "undef" unless (defined $three);
复制代码

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
3 [报告]
发表于 2015-10-12 12:30 |只看该作者
回复 1# sunzhiguolu


   
$ cat p00.pl
#!/usr/bin/perl

use strict;
use warnings;

use v5.14;
use autodie;
use Data::Dumper;

while (<DATA>) {
    chomp;
    my ($a, $b, $c) = split /\s+/;
    print Dumper([$a, $b, $c]);
}

__DATA__
ZhangSan m 15600000000
LiNa f

$ ./p00.pl
$VAR1 = [
          'ZhangSan',
          'm',
          '15600000000'
        ];
$VAR1 = [
          'LiNa',
          'f',
          undef
        ];

论坛徽章:
307
程序设计版块每周发帖之星
日期:2016-04-08 00:41:33操作系统版块每日发帖之星
日期:2015-09-02 06:20:00每日论坛发贴之星
日期:2015-09-02 06:20:00程序设计版块每日发帖之星
日期:2015-09-04 06:20:00每日论坛发贴之星
日期:2015-09-04 06:20:00每周论坛发贴之星
日期:2015-09-06 22:22:00程序设计版块每日发帖之星
日期:2015-09-09 06:20:00程序设计版块每日发帖之星
日期:2015-09-19 06:20:00程序设计版块每日发帖之星
日期:2015-09-20 06:20:00每日论坛发贴之星
日期:2015-09-20 06:20:00程序设计版块每日发帖之星
日期:2015-09-22 06:20:00程序设计版块每日发帖之星
日期:2015-09-24 06:20:00
4 [报告]
发表于 2015-10-12 13:13 |只看该作者
本帖最后由 sunzhiguolu 于 2015-10-12 13:38 编辑

回复 3# MMMIX
while (<DATA>) {
    chomp;
    my ($a, $b, $c) = split /\s+/;
    print Dumper([$a, $b, $c]);
}

您在代码中添加的 chomp 函数, 去掉了文本行末尾的换行符.
导致 split 函数分割后返回的是一个包含 (两个或三个) 元素的列表.
[$a, $b, $c]
您这个是人为的将一个值为 undef 的标量值放进了匿名数组中.

我的代码中没有用 chomp 函数去掉行末尾的换行符, 使用 split 函数分割后测试返回的数组的元素个数也是 2 个.
为什么变量 $phone_number 不是 undef.

部分测试代码如下:

  1. #!/usr/bin/perl
  2. use 5.010;
  3. use strict;
  4. use warnings;

  5. my @a_numbers1 = ("a", "b", undef);
  6. my @a_numbers2 = ("a", "b", "");
  7. say scalar (@a_numbers1);    # 3
  8. say scalar (@a_numbers2);    # 3
复制代码

论坛徽章:
145
技术图书徽章
日期:2013-10-01 15:32:13戌狗
日期:2013-10-25 13:31:35金牛座
日期:2013-11-04 16:22:07子鼠
日期:2013-11-18 18:48:57白羊座
日期:2013-11-29 10:09:11狮子座
日期:2013-12-12 09:57:42白羊座
日期:2013-12-24 16:24:46辰龙
日期:2014-01-08 15:26:12技术图书徽章
日期:2014-01-17 13:24:40巳蛇
日期:2014-02-18 14:32:59未羊
日期:2014-02-20 14:12:13白羊座
日期:2014-02-26 12:06:59
5 [报告]
发表于 2015-10-12 13:57 |只看该作者
回复 4# sunzhiguolu

也许找到bug,去回报的bug吧...

   

论坛徽章:
307
程序设计版块每周发帖之星
日期:2016-04-08 00:41:33操作系统版块每日发帖之星
日期:2015-09-02 06:20:00每日论坛发贴之星
日期:2015-09-02 06:20:00程序设计版块每日发帖之星
日期:2015-09-04 06:20:00每日论坛发贴之星
日期:2015-09-04 06:20:00每周论坛发贴之星
日期:2015-09-06 22:22:00程序设计版块每日发帖之星
日期:2015-09-09 06:20:00程序设计版块每日发帖之星
日期:2015-09-19 06:20:00程序设计版块每日发帖之星
日期:2015-09-20 06:20:00每日论坛发贴之星
日期:2015-09-20 06:20:00程序设计版块每日发帖之星
日期:2015-09-22 06:20:00程序设计版块每日发帖之星
日期:2015-09-24 06:20:00
6 [报告]
发表于 2015-10-12 14:00 |只看该作者
回复 5# jason680
如果是 bug 的话, 那就算了. 谢谢您提醒...

   

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
7 [报告]
发表于 2015-10-12 21:53 |只看该作者
本帖最后由 MMMIX 于 2015-10-12 21:54 编辑

回复 6# sunzhiguolu


    不是 bug,再把 split 文档仔细看一遍你就会发现:

1)
my ($a, $b, $c) = split /\s+/;



2)
my @f = split /\s+/;

的行为其实是不一样的。若是 $_ = "abc def\n";

那么 1) 中,$a == "abc", $b == "def", $c = ""; 而 2)中 $f[0] = "abc"; $f[1] = "def",(@f 只有两个 element)最后的空域(empty field) 被忽略了。

评分

参与人数 1信誉积分 +10 收起 理由
sunzhiguolu + 10 向您致敬, 谢谢您的指点!

查看全部评分

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
8 [报告]
发表于 2015-10-12 21:56 |只看该作者
回复 6# sunzhiguolu


    在你认为自己找到了 perl 的bug的时候,先把相关文档仔细读三遍。

论坛徽章:
307
程序设计版块每周发帖之星
日期:2016-04-08 00:41:33操作系统版块每日发帖之星
日期:2015-09-02 06:20:00每日论坛发贴之星
日期:2015-09-02 06:20:00程序设计版块每日发帖之星
日期:2015-09-04 06:20:00每日论坛发贴之星
日期:2015-09-04 06:20:00每周论坛发贴之星
日期:2015-09-06 22:22:00程序设计版块每日发帖之星
日期:2015-09-09 06:20:00程序设计版块每日发帖之星
日期:2015-09-19 06:20:00程序设计版块每日发帖之星
日期:2015-09-20 06:20:00每日论坛发贴之星
日期:2015-09-20 06:20:00程序设计版块每日发帖之星
日期:2015-09-22 06:20:00程序设计版块每日发帖之星
日期:2015-09-24 06:20:00
9 [报告]
发表于 2015-10-12 23:19 |只看该作者
本帖最后由 sunzhiguolu 于 2015-10-12 23:21 编辑

回复 7# MMMIX
终于明白了, 非常佩服您对知识严谨的态度. 向您学习了.
我在进行测试的时候, 还是没有进行全面的验证. 和您比起来差的很远...

   

论坛徽章:
307
程序设计版块每周发帖之星
日期:2016-04-08 00:41:33操作系统版块每日发帖之星
日期:2015-09-02 06:20:00每日论坛发贴之星
日期:2015-09-02 06:20:00程序设计版块每日发帖之星
日期:2015-09-04 06:20:00每日论坛发贴之星
日期:2015-09-04 06:20:00每周论坛发贴之星
日期:2015-09-06 22:22:00程序设计版块每日发帖之星
日期:2015-09-09 06:20:00程序设计版块每日发帖之星
日期:2015-09-19 06:20:00程序设计版块每日发帖之星
日期:2015-09-20 06:20:00每日论坛发贴之星
日期:2015-09-20 06:20:00程序设计版块每日发帖之星
日期:2015-09-22 06:20:00程序设计版块每日发帖之星
日期:2015-09-24 06:20:00
10 [报告]
发表于 2015-10-13 10:28 |只看该作者
本帖最后由 sunzhiguolu 于 2015-10-13 15:33 编辑

回复 5# jason680
大神您好, 我的理解如下, 如有不对之处请您给予指点, 谢谢:
部分验证代码如下:
while (<>){
    my ($name, $gender, $phone_number, $addr) = split /\s+/;
    say "\$name=$name,\$gender=$gender,\$phone_number=$phone_number\$addr=$addr" if ($phone_number eq "");
}


另外一个举例:

  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;

  4. my $format = "\@a_animals.Count=%d\n";
  5. my $str2 = my $str1 = "tiger:elephant:panda:wolf::";

  6. my @a_animals = split /:+/, $str1;
  7. printf $format, scalar (@a_animals); # 4

  8. @a_animals = split /:/, $str2;
  9. printf $format, scalar (@a_animals); # 5
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP