清华大佬耗费三个月吐血整理的几百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;