清华大佬耗费三个月吐血整理的几百G的资源,免费分享!....>>>
package Tools::Text::Format::FormTidy; use Exporter; our @ISA = qw(Exporter); our @EXPORT_OK = qw(form_tidy); use 5.014; use YAML qw(Dump); use List::Util qw(max sum); # 填充表格字符集 our $char_hash = { qw( first_head ┌ first_concat ┬ first_end ┐ middle_head ├ middle_concat ┼ middile_end ┤ last_head └ last_concat ┴ last_end ┘ form_char ─ form_concat │ ) }; sub form_tidy { my ($ref_lines, $indent) = @_; # 设置默认缩进 $indent = 1 if (not defined $indent); # 要将内容以数组的形式读入 my @lines = @{$ref_lines}; # 过滤掉空行 @lines = grep { not /^$/ } @lines; # 获取字段宽度信息和字段数组引用的数组 my ($row_width_hash, $col_field_list) = get_row_width_hash(@lines); # 字段宽度取偶数宽度 foreach my $index (keys $row_width_hash) { my $width = $row_width_hash->{$index}; $row_width_hash->{$index} = $width + 1 if ($width % 2); } # 将拆分的单词按照字段长度进行填充 my @fill_length_fields = fill_length_fields($row_width_hash, $col_field_list); # 生成分割线字段表 my @middle_fields = (); { my $char = $char_hash->{form_char}; foreach my $index (sort keys $row_width_hash) { my $width = $row_width_hash->{$index}; my $str = fill_char_length($char, $width); push @middle_fields, $str; } } # 生成中间分割线 my $middle_str = ''; { my $middle_concat = $char_hash->{middle_concat}; my $char = $char_hash->{form_concat}; $middle_str = join $middle_concat, @middle_fields; $middle_str = $char . $middle_str . $char; } # 生成头分割线 my $head_str = ''; { my $first_head = $char_hash->{first_head}; my $first_concat = $char_hash->{first_concat}; my $first_end = $char_hash->{first_end}; $head_str = join $first_concat, @middle_fields; $head_str = $first_head . $head_str . $first_end; } # 生成底边分割线 my $end_str = ''; { my $last_head = $char_hash->{last_head}; my $last_concat = $char_hash->{last_concat}; my $last_end = $char_hash->{last_end}; $end_str = join $last_concat, @middle_fields; $end_str = $last_head . $end_str . $last_end; } # 将分隔符插入每条记录 my @form_str_list; { my $char = $char_hash->{form_concat}; foreach my $record (@fill_length_fields) { my $str = join $char, @{$record}; $str = $char . $str . $char; push @form_str_list, $str; } } # 将表格分割线插入数据中 my @form_lines; { my $records_amount = scalar @form_str_list; my $amount = 0; foreach my $record (@form_str_list) { $amount++; push @form_lines, $head_str if ($amount == 1); push @form_lines, $record; push @form_lines, $middle_str if ($amount < $records_amount); push @form_lines, $end_str if ($amount == $records_amount); } } # 添加缩进 @form_lines = map { ' ' x $indent . $_ } @form_lines; # 打印表格 return (join(chr(10), @form_lines)); } sub fill_length_fields { my ($width_table, $fields_list) = @_; my @fill_length_fields_list = (); foreach my $fields (values $fields_list) { my $fields_amount = scalar(@{$fields}); my @fill_length_fields = (); foreach my $i (1 .. $fields_amount) { my $fields_width = $width_table->{$i}; my $fields_str = $fields->[$i-1]; my $fill_str = fill_str_length($fields_str, $fields_width); push @fill_length_fields, $fill_str; } push @fill_length_fields_list, [@fill_length_fields]; } return @fill_length_fields_list; } # 填充字符到指定长度 sub fill_char_length { my ($char, $length) = @_; my $fill_length = 0; if (length($char) > 1) { $fill_length = $length / 2; } else { $fill_length = $length; } my $fill_str = $char x $fill_length; return $fill_str; } # 获取一个表格的最佳列宽 sub get_row_width_hash { my @lines = @_; # 从第一样得到字段数 my $max_field = scalar(split(/\h{2,}/, $lines[0])); my @fields_str = (); my $max_row_width = {}; my $error_mode = 0; my $line_number = 0; foreach my $line (@lines) { chomp $line; $line =~ s/^\s+//; $line_number++; # 根据至少两个以上的空格来分开 my @words = split /\h{2,}/, $line; push @fields_str, [@words]; # get the max piece number my $word_count = scalar @words; if ($word_count != $max_field) { say "Not $max_field fields amount:<$line>"; $error_mode = 1; next; } exit if ($error_mode == 1); # get the max length of join line foreach my $i (1 .. scalar(@words)) { my $word = $words[$i - 1]; my $length = length($word); if (exists $max_row_width->{$i}) { my $length_i = $max_row_width->{$i}; if ($length > $length_i) { $max_row_width->{$i} = $length; } } else { $max_row_width->{$i} = $length; } } } return ($max_row_width, [@fields_str]); } # 向后填充字符串 sub fill_str_length { my ($str, $length) = @_; if (length($str) > $length) { say "str:$str length great than length:$length"; return $str; } my $fill_str = sprintf("%-${length}s", $str); return $fill_str; } 1;