Perl6::Form文本换行、表格对齐问题及内置函数报错咨询
Perl6::Form 常见问题解决方案
1. 实现文本在任意字符处换行
默认的{[[[[[[[[[[[[}格式符仅会在空格处换行,要实现单词内拆分换行,需自定义break函数,通过layout选项指定该函数,让它忽略空格直接按指定宽度拆分字符。
示例实现:
use Perl6::Form; # 自定义按字符宽度拆分的函数 sub break_any_char { my ($data_ref, $width) = @_; for ($$data_ref) { # 直接截取指定宽度的字符,不判断是否为空格 return ("", 0) unless m/\G(.{1,$width})/gc; my $result = $1; # 检查是否还有剩余内容 my $more = m/\G(?=.)/gc; return ($result, $more); } } # 使用layout指定自定义break函数 print form layout => { break => \&break_any_char }, '| Item |', '{[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[} ', ['Item', 'Word1 Super_________long________________word1'];
运行后长单词会在指定宽度的任意字符处拆分,达成你期望的换行效果。
2. 表格列对齐异常的原因
问题出在Score列的宽度不足:{[[[}仅分配了3个字符宽度,但@score里的115555555有9位,超出宽度后自动换行到下一行,挤占了blah2对应的Score位置,导致整行错位。
解决方法:
- 调整Score列的格式符宽度,比如把
{[[[}改成{[[[[[[[[}(9位宽度),容纳最长的score值; - 或者保持宽度,结合第一个问题的自定义break函数,让长score值按字符拆分换行,避免挤占下一行位置。
修正后的代码示例:
use Perl6::Form; my @name=('blah1', 'blah2'); my @score=('115555555', '12'); my @time=(1.1, 1.3); my @normalized=(100, 101); print form '-------------------------------------------', 'Name Score Time | Normalized', '-------------------------------------------', '{[[[[[[[[[[[[} {[[[[[[[[} {II} | {]]].[[} ', \@name, \@score,\@time, \@normalized;
调整后115555555可在9位宽度内完整显示,blah2的各项值就能和表头对齐。
3. 修复break_width函数的编译与初始化问题
原函数存在多个语法错误和参数问题,逐一修复如下:
- 正则表达式末尾补分号:
my $single_char = qr{ $ws | [\n\r]+ | . }后添加;; - 正则中引用变量:将
single_char{1,$width}改为$single_char{1,$width}; - 给$ws加默认值:参数定义改为
$ws = qr/\s+/,避免未传参时报错; - 替换中文引号:把
""换成英文双引号""; - 优化正则匹配逻辑:确保
$ws在正则中正确解析。
修复后的函数:
sub break_width { my ($data_ref, $width, $ws = qr/\s+/) = @_; for ($$data_ref) { # Treat any squeezed or vertical whitespace as a single character # (since they'll subsequently be squeezed to a single space) my $single_char = qr{ $ws | [\n\r]+ | . }; # Give up if there are no more characters to grab... return ("", 0) unless m/\G ($single_char{1,$width}) /gcx; # Squeeze the resultant substring... (my $result = $1) =~ s/ $ws | [\n\r] / /gx; # Check for any more data still to come... my $more = m/\G (?= .* \S) /gcx; # Return the squeezed substring and the "more" indicator... return ($result, $more); } }
现在调用时若不传$ws,会默认匹配任意空白字符,编译和运行均不会报错,同时保留了原函数的空白压缩逻辑。
内容的提问来源于stack exchange,提问作者Jean
相关产品推荐
相关产品推荐

