blue1025的个人空间 https://blog.eetop.cn/mj8051 [收藏] [复制] [分享] [RSS]

空间首页 动态 记录 日志 相册 主题 分享 留言板 个人资料

日志

PERL 第13章 字符串与排序

已有 3880 次阅读| 2008-9-27 14:51 |个人分类:PERL

SOURCE HTML: http://socvista.com/bbs/redirect.php?fid=71&tid=948&goto=nextnewset

PERL 第13章 字符串与排序

== Perl 的二八效应
Perl 被设计用来解决 90% 的 text 处理问题和 10% 的其他问题,所以Perl的文本处理能令非常强。

== 寻找并定位字串(首次发生)
举个例子:
$where = index($big, $small);
返回值是一个index,指示子串首字母的位置。这个位置是从0开始计数的。例如
my $stuff = "howdy world!";
my $where = index($stuff, "wor");
返回值为6。

== 寻找并定位字串(指定位置后的首次发生)
举个例子:
$where = index($big, $small, $start);
这里的第三个参数,指示了搜索需要从第 start 个字符开始。

== 搜索失败的返回值
-1

== 寻找并定位字串(最后一次发生)
使用 rindex 。
$where = rindex($big, $small);

== 寻找并定位字串(指定位置前的最后一次发生)
使用方法:
$where = index($big, $small, $end);
这里的第三个参数,指示了搜索需要在第 end 个字符之前进行,之后的字符不在搜索范围内。

操作子字符串

== 获取子串(指定长度)
$part = substr($string, $init_position, $length);
这里的init_position是从0开始的。

== 获取子串(直到结尾)
$part = substr($string, $init_position);
省略第三个length参数就表示从init_position开始直到结尾。

== 获取子串(反向定位)
反向定位就是从结尾处开始计数。
$part = substr($string, $init_position, $length);
这里的init_position是从-1开始的,最后一个字符是-1,然后-2、-3以此类推。

== 如果指定的length过长
最多只返回到结尾处的字符串。但是Perl不会报错。

== 替换子字符串
语法,
substr($string, $init_position, $length, $replace_str);
另外的方法是:
1. substr($string, $init_position, $length) = $replace_str;
2. substr($string, $init_position) =~ s/$original_sub_str/$replace_str/g;

将数据用sprintf格式化

== sprintf一般格式
sprintf的格式和printf类似。但是sprintf只会返回所需的字符串而不会打印它。
my $date_tag = sprintf "%4d/%02d/%02d %02d:%02d:%02d", $yr, $mo, $da, $h, $m, $s;
注意,这里格式中 %02d,意味着宽度为2位的十进制数,前面的0表示不足两位的话,前面补零。所以,实际格式如下:
2008/08/26 08:41:05

== 用 sprintf 打印货币格式
如 $12,345,678.90;
方法如下,
sub big_money {
  my $number = sprintf "%.2f", shift @_;
  1 while $number =~ s/^(-?\d+)(\d\d\d)/$1,$2/;  # 对连续的4个以上的数字,在最后三个数字前加上逗号
  $number =~ s/^(-?)/$1\$/;  # 在数字前面加上$符号,如果有-号则在-号后面加上$符号。
  $number;
}

高级排序

== Perl 的高级排序手段
语法:
my @sorted_array = sort  sub_sort_method  @original_array;
这里的 sub_sort_method 就是我们制定的排序策略,一般是一个sub routine 的名字,或者其代码。
示例:
my @result = sort by_number @some_numbers;  # sub by_number {$a <=> $b}
my @result = sort { $a <=> $b} @some_numbers;  # <=> 符号表示数字的比较和排序
my @descending = reverse sort { $a <=> $b} @some_numbers;
my @string = sort {$a cmp $b} @any_strings;  # cmp 表示字符串的比较和排序
my @string = sort {"\L$a" cmp "\L$b"} @any_strings;  # \L表示忽略大小写
Perl排序的理念是:你只要告诉他两个元素的比较关系(用-1,0,1表示),Perl就会为你完成任意长度的比较。
比如 {$a <=> $b} 其实表示的是
  if ($a < $b) {-1} elsif ($a > $b) {1} else {0}
<=>符号只是一个缩写。Perl只要知道我们的sort类型,就会为任意多个元素完成排序。

== 根据value对hash表的key值进行排序
首先,要理解我们无法对hash表进行排序,不然就不叫hash了。
不过,根据hash表的value我们可以为相应的key实现排序。示例如下
sub by_score {$score{$b} <=> $score{$a}};  # $b在前面是因为我们要从大到小降序排列
my %score = ('barney" => 195, "fred" => 205, "dino" => 30);
my @ranking = sort by_score keys %score;  # 注意要这样阅读 sort by_score (keys %score)
注意,by_score不是对key直接做比较,而是根据key比较value,然后反过来对key进行排序。通俗的例子就是张三和李四光凭名字无法排 序,但是根据名字,我们找到他们的考试成绩,然后反过来,对名字进行排序。这就是  {$score{$b} <=> $score{$a}} 的工作。

== 二重排序与多重排序
前面的例子中,按照value进行了排名,但是如果value相同怎么办?如果我们希望对value相同的人按照字母顺序再细排,该怎么做呢?答案如下
sub by_score_and_name {
  {$score{$b} <=> $score{$a}}  # 按照value对key做降序排列
  or
  $a cmp $b # 按照字母顺序再排序
}
其实意思也很好理解。因为value相同,因此比较结果返回0,这个时候结果就由 or 的另一部分来决定了。
上面的例子是二重排序。同理可以推导多重排序的方法。






点赞

评论 (0 个评论)

facelist

您需要登录后才可以评论 登录 | 注册

  • 关注TA
  • 加好友
  • 联系TA
  • 0

    周排名
  • 0

    月排名
  • 0

    总排名
  • 0

    关注
  • 13

    粉丝
  • 16

    好友
  • 15

    获赞
  • 23

    评论
  • 2824

    访问数
关闭

站长推荐 上一条 /2 下一条

小黑屋| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-4-19 10:36 , Processed in 0.014839 second(s), 7 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
返回顶部