免费注册 查看新帖 |

Chinaunix

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

请教perl高手,谢谢。 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-02-27 22:37 |只看该作者 |倒序浏览
各位老大,我是个perl门外汉,呵呵。
想编个小程序简化一下工作。请各位援手。      

一个字符串匹配尾部用$不生效是什么原因?

用户正则表达式如何匹配如下面的字符串,后面的 数字 to 数字 需要分解成连续的条目,谢谢。
问题是下面的一行字符串,把单独的数字提取出来,用to 连接的两个数中间的数值都填上
port trunk allow-pass vlan 3 to 19 21 to 25 29 32 to 35 37 to 41 43 to 44 48 52 to 56 59 to 64 66 to 70
输出结果
port trunk allow-pass vlan 3
port trunk allow-pass vlan 4
port trunk allow-pass vlan 5
... ...
port trunk allow-pass vlan 18
port trunk allow-pass vlan 19
port trunk allow-pass vlan 21
port trunk allow-pass vlan 22
... ...
port trunk allow-pass vlan 25
port trunk allow-pass vlan 29

... ...

论坛徽章:
0
2 [报告]
发表于 2013-02-27 23:08 |只看该作者
啥意思?没看明白呢

论坛徽章:
0
3 [报告]
发表于 2013-02-27 23:11 |只看该作者
把port trunk allow-pass vlan 后面的数字序列拆成多行。“to” 表示前后两个数字之间是连续的。

论坛徽章:
2
CU大牛徽章
日期:2013-04-17 11:46:28CU大牛徽章
日期:2013-04-17 11:46:39
4 [报告]
发表于 2013-02-27 23:22 |只看该作者
本帖最后由 cdtits 于 2013-02-27 23:31 编辑
  1. #!/usr/bin/env perl

  2. while (<DATA>) {
  3.     /(.*?)(?=\d+)/, my $v = $1;
  4.     my @dat = /(\d+)\s*to\s*(\d+)/g;
  5.     for (my $i = 0; $i < $#dat; $i += 2) {
  6.         my ($j, $k) = @dat[$i, $i+1];
  7.         print "$v$_\n" for ($j..$k);
  8.     }
  9. }

  10. __DATA__
  11. port trunk allow-pass vlan 3 to 19 21 to 25 29 32 to 35 37 to 41 43 to 44 48 52 to 56 59 to 64 66 to 70
复制代码

论坛徽章:
0
5 [报告]
发表于 2013-02-27 23:34 |只看该作者
谢谢,很强大。

帮我再看看,29  和 48 没有输出。

谢谢。
在线等。:)

论坛徽章:
0
6 [报告]
发表于 2013-02-27 23:36 |只看该作者
  1. #!perl

  2. use 5.014;

  3. my $str = 'port trunk allow-pass vlan 3 to 19 21 to 25 29 32 to 35 37 to 41 43 to 44 48 52 to 56 59 to 64 66 to 70';
  4. my $head_str = 'port trunk allow-pass vlan';
  5. my @ranges = $str =~ /(\d+)\s+to\s+(\d+)/g;
  6. my @numbers = $str =~ /\d+\s+(\d+)\s+\d+/g;
  7. while (@ranges) {
  8.   my $start_number = shift @ranges;
  9.   my $end_number = shift @ranges;
  10.   my @range_number = ($start_number .. $end_number);
  11.   push @numbers, @range_number;
  12. }

  13. foreach my $number (sort { $a <=> $b } @numbers) {
  14.   say "$head_str $number";
  15. }
复制代码

论坛徽章:
2
CU大牛徽章
日期:2013-04-17 11:46:28CU大牛徽章
日期:2013-04-17 11:46:39
7 [报告]
发表于 2013-02-27 23:56 |只看该作者
  1. #!/usr/bin/env perl

  2. my @dat;
  3. my $v;
  4. my $_ = 'port trunk allow-pass vlan 3 to 19 21 to 25 29 32 to 35 37 to 41 43 to 44 48 52 to 56 59 to 64 66 to 70';
  5. /(.*?)(?=\d+)/, $v = $1;
  6. while (/(\d+)(\s*to\s*(\d+))?/g) {
  7.     if (!defined $3) {
  8.         push @dat, $1; next;
  9.     }
  10.     push @dat, $_ for ($1..$3);
  11. }
  12. print "$v$_\n" for @dat;
复制代码

论坛徽章:
0
8 [报告]
发表于 2013-02-27 23:56 |只看该作者
谢谢Perlvim cdtits
解决了问题,还学到了处理思路,强大。

论坛徽章:
0
9 [报告]
发表于 2013-02-28 12:17 |只看该作者
  1 #!/usr/bin/perl -w
  2 my $string="port trunk allow-pass vlan 3 to 19 21 to 25 29 32 to 35 37 to 41 43 to 44 48 52 to 56 59 to 64 66 to 70";
  3 my @list=();
  4 while($string=~m/((\d+)\s+to\s+(\d+))/){
  5         for(my $i=$2;$i<=$3;$i++){
  6                 push @list,$i;
  7         }
  8         $string=~s/$1/@list/;
  9         @list=();
10 }
11 print "$string\n";

论坛徽章:
5
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015年亚洲杯之朝鲜
日期:2015-03-13 22:47:33IT运维版块每日发帖之星
日期:2016-01-09 06:20:00IT运维版块每周发帖之星
日期:2016-03-07 16:27:44
10 [报告]
发表于 2013-02-28 12:28 |只看该作者
本帖最后由 blackold 于 2013-02-28 12:28 编辑

try
  1. #!/bin/perl

  2. use warnings;
  3. use strict;

  4. my $str = 'port trunk allow-pass vlan 3 to 19 21 to 25 29 32 to 35 37 to 41 43 to 44 48 52 to 56 59 to 64 66 to 70';
  5. my($head,$numberstr) = $str =~ /^(\D+)(\d.*)/;
  6. $numberstr =~ s/ +to +/to/g;
  7. my @numbers = map {/(\d+)to(\d+)/?($1..$2):$_} split / /,$numberstr;
  8. print "$head$_\n" foreach @numbers;
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP