免费注册 查看新帖 |

Chinaunix

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

将文本格式转换成表格形式(使用等宽字体显示) [复制链接]

论坛徽章:
0
跳转到指定楼层
[收藏(0)] [报告]
发表于 2013-03-31 15:46 |只看该作者 |正序浏览
30可用积分
本帖最后由 Perlvim 于 2013-03-31 15:49 编辑

一个由二个空格以上分隔的列
colname1   colname2   colname3
str1       str2      str3
str4       str5      str6

转换成:

------------------------------
colname1 | colname2 | colname3
------------------------------
str1        | str2     | str3
------------------------------
str4        | str5     | str6
------------------------------


或者其中有一个单元格为空

colname1   colname2   colname3
str1                  str3
str4       str5       str6

转换成:

------------------------------
colname1 | colname2 | colname3
------------------------------
str1        |                | str3
------------------------------
str4        | str5         | str6
------------------------------

其中一个单元格有换行
colname1   colname2   colname3
str1       str2       str3 str3
                      str3
str4       str5       str6

-------------------------------
colname1 | colname2 | colname3
-----------------------------
str1        | str2           | str3 str3
              |                  | str3
-----------------------------
str4        | str5           | str6
-----------------------------

论坛徽章:
7
戌狗
日期:2013-12-15 20:43:38技术图书徽章
日期:2014-03-05 01:33:12技术图书徽章
日期:2014-03-15 20:31:17未羊
日期:2014-03-25 23:48:20丑牛
日期:2014-04-07 22:37:44巳蛇
日期:2014-04-11 21:58:0915-16赛季CBA联赛之青岛
日期:2016-03-17 20:36:13
18 [报告]
发表于 2013-04-02 10:05 |只看该作者
kk861123 发表于 2013-04-02 05:55
给变量起个好名字吧,别总是阿猫阿狗的

{:3_188:}

  1. my $cat  = 'cat';
  2. my $dog = 'dog';
复制代码

论坛徽章:
0
17 [报告]
发表于 2013-04-02 09:55 |只看该作者
rubyish 发表于 2013-04-02 09:48
我也是!
基本靠猜。

给变量起个好名字吧,别总是阿猫阿狗的{:3_185:}

论坛徽章:
7
戌狗
日期:2013-12-15 20:43:38技术图书徽章
日期:2014-03-05 01:33:12技术图书徽章
日期:2014-03-15 20:31:17未羊
日期:2014-03-25 23:48:20丑牛
日期:2014-04-07 22:37:44巳蛇
日期:2014-04-11 21:58:0915-16赛季CBA联赛之青岛
日期:2016-03-17 20:36:13
16 [报告]
发表于 2013-04-02 09:48 |只看该作者
dahe_1984 发表于 2013-04-01 07:06
回复 6# rubyish

呵呵,您写的代码永远这么高深莫测,我总是看不懂

我也是!{:3_188:}
基本靠猜。{:3_203:}

论坛徽章:
7
戌狗
日期:2013-12-15 20:43:38技术图书徽章
日期:2014-03-05 01:33:12技术图书徽章
日期:2014-03-15 20:31:17未羊
日期:2014-03-25 23:48:20丑牛
日期:2014-04-07 22:37:44巳蛇
日期:2014-04-11 21:58:0915-16赛季CBA联赛之青岛
日期:2016-03-17 20:36:13
15 [报告]
发表于 2013-04-02 09:03 |只看该作者
我的 V2:
  1. #!/usr/bin/perl
  2. sub table {
  3.     my %i = ( align => 1, title => '', space => 1, samewidth => 1 );
  4.     @_ % 2 ? do { $i{data} = shift } : do { %i = ( %i, @_ ) };
  5.     my ( $p, $t, $c, $w ) = @i{qw/align title space samewidth/};
  6.     my @d = @{ $i{data} };
  7.     my ( $l, $s, $e, @l, $L ) = ( 0, $" x $c, scalar @{ $d[0] } );
  8.     my %T = (
  9.         b => [qw(: - :)],
  10.         m => [qw(: + :)],
  11.         h => '-', v => '|'
  12.     );
  13.    
  14.     @l = $w
  15.     ? do { map $l < $_ && ( $l = $_ ), map length, map @$_, @d; ($l+$c*2) x $e }
  16.     : do { map {
  17.              my ( $l, $a ) = ( 0, $_ );
  18.              map $l < $_ && ( $l = $_ ), map length $d[$_][$a], 0 .. $#d; $l + $c * 2
  19.            } 0 .. $e - 1 };
  20.                
  21.     $L += $_ for @l;
  22.     $L += $e - 1;
  23.    
  24.     my ( $hm, $hb ) =
  25.       map { $T{$_}[0].join( $T{$_}[1], map $T{h} x $_, @l )."$T{$_}[2]\n"
  26.     } qw/m b/;
  27.     my $title = "$T{v}$s$t".$" x ( $L - $c - length $t )."$T{v}\n";
  28.     my $A = sub {
  29.       my $i;
  30.       map { my $x = $" x ( $l[$i++] - $c - length ); $p ? "$s$_$x" : "$x$_$s" } @_;
  31.     };
  32.     my $text = sub { $T{v} . join( $T{v}, $A->(@_) ) . "$T{v}\n" };
  33.     $hb.( $t ? $title.$hb : '' ).join( $hm, map $text->(@$_), @d ).$hb;
  34. }

  35. my @a = map [split], <DATA>;

  36. print table \@a;
  37. print table data => \@a, align => 1, space => 0;
  38. print table data => \@a, samewidth => 0, title => 'Africa', align => 0, space => 1;
  39. __DATA__
  40. Abid        Banjul       Conakry        Harare
  41. Accra       Bissau       Dakar          Johanne
  42. Addis       Blantyre     Dar_es_Salaam  Juba
  43. Algie       Brazzaville  Djibouti       Kampala
复制代码

论坛徽章:
2
射手座
日期:2014-10-10 15:59:4715-16赛季CBA联赛之上海
日期:2016-03-03 10:27:14
14 [报告]
发表于 2013-04-01 22:29 |只看该作者
回复 14# Perlvim


    是的,应该去当前列最大的,用个hash保存,应该就能实现,有时间我再改改

论坛徽章:
0
13 [报告]
发表于 2013-04-01 22:16 |只看该作者
回复 12# yinyuemi

非常感谢音乐迷的梦幻作品。

每个字段的宽度不同,默认取的是最长字段宽度,这样浪费较大。应当取当前列中最宽的长度作为当前列的宽度。

实际应用中,多个字段,通常一个字段较长,必须要分行处理。就好像 <<Perl 口袋书>>中,大量的使用表格型数据。

在不同的终端上,表格宽度需要调整,所以,这个算法要想成为实用的算法,还需要稍微改进一下。


   

论坛徽章:
0
12 [报告]
发表于 2013-04-01 20:23 |只看该作者
回复 11# yinyuemi

就假设没有这样的异常情况,因为这些异常情况都可以用单独的程序进行修正

论坛徽章:
2
射手座
日期:2014-10-10 15:59:4715-16赛季CBA联赛之上海
日期:2016-03-03 10:27:14
11 [报告]
发表于 2013-04-01 18:46 |只看该作者
回复 3# Perlvim


    我觉得这两种情况的确不好判断,你可以考虑像excel的输出格式,比如
  1. abc     abcd    "ief
  2. eing"
  3. din     dge     kxd
  4.                ge
复制代码
上面" ",指明了ief 和eing是在一起的,而kxd和ge不是

论坛徽章:
0
10 [报告]
发表于 2013-04-01 11:45 |只看该作者
本帖最后由 Perlvim 于 2013-04-01 11:50 编辑

代码翻译一下,代码思维极具跳跃性,我也是基本靠猜。
  1. #!/usr/bin/perl
  2. sub table {
  3.     # 传递参数,如果只有一个参数,就设置为默认对齐方式
  4.     my %i = ( @_, @_ % 2 ? 0 : () );
  5.     # 如果有 data 就取其作为数据项
  6.     my @dat = @{ $i{data} || shift };
  7.     # 如果有 align 就取其作为对齐参数
  8.     my $p = $i{align} // 0;
  9.     # 边框字符表
  10.     my %T   = (
  11.         t => [ qw(┌ ┬ ┐) ],
  12.         m => [ qw(├ ┼ ┤) ],
  13.         b => [ qw(└ ┴ ┘) ],
  14.         h => '─',
  15.         v => '│',
  16.     );
  17.     # 最长的字段长度
  18.     my $l = 0;
  19.     # 典型施瓦茨变换格式
  20.     # 获取最长字段的数值
  21.     map $l < $_ && ( $l = $_ ),
  22.     # 获取长度
  23.     map length,
  24.     # 解引用
  25.     map @$_, @dat;
  26.     # 获取字段数量
  27.     my $e = scalar @{ $dat[0] };
  28.     # 生成表格框架
  29.     # 开头字符 + 分界符 + 字段最长长度 + 2个空格 + 分界符 + 末尾字符
  30.     my ( $ht, $hm, $hb ) = map {
  31.         $T{$_}[0] . join( $T{$_}[1], ( $T{h} x ( $l + 2 ) ) x $e ) . "$T{$_}[2]\n";
  32.     } qw/t m b/;
  33.     # 生成将数据按照长度插入分隔符的子程序
  34.     my $al = sub { map { my $s = $" x ( 1 + $l - length ); $p ? "$s$_ " : " $_$s" } @_ };
  35.     # 生成文本解析子程序
  36.     my $text = sub { $T{v} . join( $T{v}, $al->(@_) ) . "$T{v}\n" };
  37.     # 增加前后表头,并生成最终结果
  38.     $ht . join( $hm, map $text->(@$_), @dat ) . $hb;
  39. }

  40. # 将内容保存为数组的引用的数组
  41. my @a = map [split], <DATA>;
  42. # 两种参数传递风格,可以传递对其方式,也可以默认使用左对齐
  43. print table \@a;
  44. print table data => \@a, align => 1;
  45. print table data => \@a;
复制代码

论坛徽章:
0
9 [报告]
发表于 2013-04-01 11:10 |只看该作者
本帖最后由 Perlvim 于 2013-04-01 11:11 编辑

好好研究中。。
  1. ┌───────┬───────┬───────┬───────┐
  2. │ Abidjan      │ Banjul       │ Conakry      │ Harare       │
  3. ├───────┼───────┼───────┼───────┤
  4. │ Accra        │ Bissau       │ Dakar        │ Johannesburg │
  5. ├───────┼───────┼───────┼───────┤
  6. │ Addis_Ababa  │ Blantyre     │Dar_es_Salaam │ Juba         │
  7. ├───────┼───────┼───────┼───────┤
  8. │ Algiers      │ Brazzaville  │ Djibouti     │ Kampala      │
  9. └───────┴───────┴───────┴───────┘
复制代码
  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP