首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >忽略某些unicode字符串的正确字符串长度的Rust字符串格式化程序

忽略某些unicode字符串的正确字符串长度的Rust字符串格式化程序
EN

Stack Overflow用户
提问于 2021-01-21 05:29:39
回答 1查看 365关注 0票数 1

我在用println!若要使用以下方法对列进行排列:

代码语言:javascript
复制
fn main() {
    let name_col_w = 24;
    let col_w = 9;

    println!("{:<0name_col_w$}{:<0col_w$}",
    "COL A",
    "COL B",
    name_col_w=name_col_w,
    col_w=col_w,
    
    );
    
    println!("{:<0name_col_w$}{:<0col_w$}",
    "000",
    "OOO",
    name_col_w=name_col_w,
    col_w=col_w,
    );    
    
    println!("{:<0name_col_w$}{:<0col_w$}",
    "麒麟24",
    "OOO",
    name_col_w=name_col_w,
    col_w=col_w,
    );
}

这一产出如下:

代码语言:javascript
复制
COL A                   COL B    
000                     OOO      
麒麟24                    OOO 

注意,unicode字符正在超出列的界限(第二列不是全部对齐)。但是,字符串的长度小于限制(24)。

代码语言:javascript
复制
extern crate unicode_width;
use unicode_width::UnicodeWidthStr;

println!("{}","麒麟24".len()); // 8
println!("{}","麒麟24".chars().count()); // 4
println!("{}", UnicodeWidthStr::width("麒麟24")); // 6

看起来,Rust格式语法实现测量的宽度错误,因为字符串应该能够适应分配的24宽度。

是否有办法使生锈识别正确的字符串宽度和正确的格式?还是我只是做了些根本错误的事?

(工作示例这里)

我正在使用来自锈病病案的字符串格式语法。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-01-21 07:00:45

从技术上讲,这里没有不正确的字符串长度。

问题是,大多数单空间字体根本不处理CJK,要么不支持CJK(因此退回到其他方面,这是最有可能的),要么不对CJK进行单步处理:单空间字体的全部要点是:

所有字母和字符占用相同的水平空间。

但是这里显然不是这样的,因为您自己的对齐清楚地显示了麒麟占用比3个ascii字符更多的水平空间:

代码语言:javascript
复制
"麒麟",
"OOO",

因此,虽然麒麟24是4个字符,但它占用了略多于5个的视觉空间,因此填充到24个字符时抛出了对齐。

我认为除了使用足够完整的单空间字体,在您所期望的整个字符范围内使用单空间字体,或者使用GUI工具包(不会受到此问题的影响)之外,没有任何解决方案。我不确定即使是TUI/原始终端输出也能解决这个问题。

事实上,这甚至可能是GUI中的一个问题,因为如果你真的想把一切都做好,你需要通过整个渲染管道,然后测量实际的“位图”大小(实际显示在屏幕上的是什么)。

在POSIX2001中,wcwidth(3)wcswidth(3)应该帮助查询终端,以了解字符或字符串的宽度,这可能会或不可能工作,这取决于终端,并且只有一些在实际终端中工作的概率(例如,在我的实际终端中,麒麟恰好有4个单元格,显然使用的字体集并不是这样使用的)。

您可能遇到的另一个问题是count和字符串填充工作中的代码点,由于例如组合代码点,这已经是非常不正确的,即使使用在美国英语中可能遇到的表单也是微不足道的:

代码语言:javascript
复制
println!("[{:<4}]", "é");
println!("[{:<4}]", "e\u{0301}");

输出

代码语言:javascript
复制
[é   ]
[é  ]

因为第二行使用两个代码点来处理一个单一的字素簇,这使得对齐的计算变得简单(除了前两个代码点转换为一个单一的字素簇外,它增加了2个空间编码点以达到4个,因此我们以3个字素簇而不是我们所期望的4个为结尾)。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65821654

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档