emoji对齐 特殊字符对齐 文本对齐

news2024/11/29 0:46:28

emoji如何对齐 特殊字符如何对齐 高级文本对齐

问题引出

我们在程序打印输出时,如何我们所输出的字符中包含emoji文本,或者其它特殊的字符文本,则我们的打印对齐效果将出现错位。以下代码复现了这一效果(tips: 马老师 前面的 | 符号是为了观察对齐效果):

# -*- coding:UTF-8 -*-

# region 引入必要依赖
from DebugInfo.DebugInfo import *

# endregion



if __name__ == "__main__":
    画板 = 打印模板()
    画板.打印空行(2)

    画板.准备表格()
    画板.添加一行('序号', '姓名', '自评', '班主任').修饰行(青字)  # 作为标题行
    画板.添加一行('1', '小红', '我很开朗', '|马老师')
    画板.添加分隔行()
    画板.添加一行('2', '猪小明', '我得了很多小花 ❌', '|马老师')
    画板.添加分隔行()
    画板.添加一行('3', '赵虹', '我有爱心♥', '|马老师')
    画板.添加分隔行()
    画板.添加一行('4', '张天志', '我是女生♀️我有长头发', '|马老师')

    画板.添加空行()
    画板.展示表格()

👆以上代码的运行打印对齐如下:

20231104175834

我们可以观察到,猪小明行,马老师靠前了
我们又可以观察到,张天志行,马老师靠后了

原因解释

为什么会出现上面的对齐的现象呢?这就要从字体说起了。
我们电脑上,所显示的符号肯定是通过某一个字体来显示的。所以同一个字,我们在宋体下看到的效果,和在黑体下看到的效果,是不一样的。

一个字符,显示其效果所占用的屏幕像素数量,称为字符的显示像素宽度;为方便其见,我们将字符的像素宽度相对于英文字符空格所占用的像素宽度的比值,做为下文我们要描述的字符显示宽度值。

  • 显然,英文空格的字符显示宽度值是 1
  • 一个英文字符(大写和小写)的显示宽度值是 1
  • 对于以下显示的楷体字体下的中文,一个字符的显示宽度值是 2
    20231104181232

显示,对于任何可以在电脑上显示的字符,其都有一个显示宽度,只是不同的字符,在不同的字体下,其显示宽度值不同罢了。

有了以上规律后,我们如果需要对齐文本,就会比较容易了。我们计算字符的显示宽度,根据其显示宽度,计算并补充对应数量的空格后,文本就可以达到对齐的效果。

那现在来说上面马老师对不齐的问题。根据上文中的对齐原理的解释,马老师对不齐,肯定是文本中存在了这样的字符,这字符计算的显示宽度,与其实际显示所占用的宽度不一致,导致在补充空格时空格数量计算错误。

找出真凶

在上面的表格中,我们发现符号 ❌ ♥ ♀️ 是不常的字符。我们把这几个字符拿掉,再来观察对齐效果,如下👇:

# -*- coding:UTF-8 -*-

# region 引入必要依赖
from DebugInfo.DebugInfo import *

# endregion



if __name__ == "__main__":
    画板 = 打印模板()
    画板.打印空行(2)

    画板.准备表格()

    画板.添加一行('序号', '姓名', '自评', '班主任').修饰行(青字)  # 作为标题行
    画板.添加一行('1', '小红', '我很开朗', '|马老师')
    画板.添加分隔行()
    # 画板.添加一行('2', '猪小明', '我得了很多小花 ❌', '|马老师')
    画板.添加一行('2', '猪小明', '我得了很多小花 ', '|马老师')
    画板.添加分隔行()
    # 画板.添加一行('3', '赵虹', '我有爱心♥', '|马老师')
    画板.添加一行('3', '赵虹', '我有爱心', '|马老师')
    画板.添加分隔行()
    # 画板.添加一行('4', '张天志', '我是女生♀️我有长头发', '|马老师')
    画板.添加一行('4', '张天志', '我是女生我有长头发', '|马老师')

    画板.添加空行()
    画板.展示表格()

👆以上代码运行效果如下👇:

20231104222547

嗯,对齐效果非常漂亮。
所以,我们将问题的焦点放在符号 ❌ ❤ ♀️ 这三个字符上。 以下代码打印并显示了这三个字符的显示宽度和实际占用宽度。

# -*- coding:UTF-8 -*-

# region 引入必要依赖
from DebugInfo.DebugInfo import *

# endregion



if __name__ == "__main__":
    画板 = 打印模板()
    画板.打印空行(2)

    画板.准备表格()

    画板.添加一行('字符','显示宽度值').修饰行(青字)
    画板.添加分隔行()
    画板.添加一行('❌|',显示宽度('❌'))
    画板.添加一行('♥|',显示宽度('♥'))
    画板.添加一行('♀️|',显示宽度('♀️'))

    画板.添加空行()
    画板.展示表格()

👆以上代码运行效果如下👇:
20231104213053
上图我们可以看到(注意看参考符号 | 的位置):

  • 字符 ❌ 显示占用宽度为1, 计算的显示宽度是2 (这将导致在对齐补空格时,少补一个空格)
  • 字符 ♥ 显示占用宽度为1,计算的显示宽度也是1 (实际显示宽度和计算显示宽度一致,对齐补齐空格正常)
  • 字符 ♀️ 显示占用宽度为2,但计算的显示宽度为1 (这将导致在对齐补空格时,多补一个空格)

所以,对齐出错的根本原因在于符号 ♥ 和 ♀️ 在终端显示时,显示这两个字符所占用的字符宽度与计算的字符宽度不一致,导致在计算对齐补空格时,补了错误数量的空格。

补救措施

有了以上的分析,我们知道了出现对齐错位的根本原因在于部分特殊的字符显示宽度值的计算与实际不符导致,那么我们对应的解决方案也就明朗了:修正特殊字符的显示宽度值

如下的代码,我们指定了特殊字符的显示宽度值,并将其告诉了【打印模板对象】(这里是画板),然后我们又打印显示了带有特殊字符的文本,观察其对齐效果:

# -*- coding:UTF-8 -*-

# region 引入必要依赖
from DebugInfo.DebugInfo import *

# endregion



if __name__ == "__main__":
    画板 = 打印模板()
    画板.打印空行(2)

    画板.准备表格()
    画板.设置特殊字符宽度字典({'❌': 1, '♀': 2})  # 修正特殊符号的显示宽度值

    画板.添加一行('序号', '姓名', '自评', '班主任').修饰行(青字)  # 作为标题行
    画板.添加一行('1', '小红', '我很开朗', '|马老师')
    画板.添加一行('2', '猪小明', '我得了很多小花❌', '|马老师')
    画板.添加一行('3', '赵虹', '我有爱心♥', '|马老师')
    画板.添加一行('4', '张天志', '我是女生♀️我有长头发', '|马老师')

    画板.添加空行()
    画板.展示表格()

👆上面的代码中,请留意 设置特殊字符宽度字典 方法,其修正了符号 ❌和 ♀️ 的显示宽度值,这帮助程序正确的理解和计算了字符的实际显示宽度,从而在对齐补齐空格时,可以补齐正确数量的空格。

20231104222101

其它的坑

在以上的分析过程中,我们所提到,所有在电脑上显示处理的符号,都依赖于字体,这也就是说,在不同的字体下,同一个符号可能显示的宽度(相对于空格或者符号 -),是有可能不同的,现观察到的部分字体中,英文字符的宽度如果计算为单位1,中文字符的宽度是1.5,在这种非整数倍的字体下,遇到中英文混合情况时,对齐处理是非常难的,甚至是无法做到的。

对于特殊字符,同样在不同的字体下,其显示宽度也是不同的,在实际的应用中要多加留意处理。

另外,为了方便文本对齐的计算,大家在实际使用时,需要注意终端所使用的字体是否是等宽字体,非等宽字体下,可能出现字体宽度不是整数的情况,对齐处理效果会受到影响。

小结

非常感谢大家的关注和阅读,如果哪里有些的不对的地方,望批评指出,以便及时修正。

对于特殊字符,同样在不同的字体下,其显示宽度也是不同的,在实际的应用中要多加留意处理。

另外,为了方便文本对齐的计算,大家在实际使用时,需要注意终端所使用的字体是否是等宽字体,非等宽字体下,可能出现字体宽度不是整数的情况,对齐处理效果会受到影响。

小结

非常感谢大家的关注和阅读,如果哪里有些的不对的地方,望批评指出,以便及时修正。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1172277.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

“第六十天”

SRAM和DRAM: DRAM:动态RAM(随机存期存储器),是使用栅极电容存储信息的; SRAM:静态RAM,是使用双稳态触发器存储信息的。 重点在于DRAM由于要通过电容放电来表示信息,所…

R语言gplots包的颜色索引表--全平台可用

R语言gplots包的颜色索引表–全平台可用

【Liunx系统编程】命令模式3

目录 一,zip/unzip压缩指令 二,tar打包/压缩/解包指令 三,uname获取系统信息指令 四,Liunx下常用且重要的按键和关机指令 五,文件之间的互传 1,Windows与Linux之间的互传 2,Linux系统之间…

初识JVM

1. JVM内存区域划分 jvm在启动的时候,会申请到一整个很大的内存区域。整个一大块区域,不太好用。为了更方便使用,把整个区域隔成了很多区域,每个区域都有不同的作用。 本地方法栈 此处提到的栈和数据结构中的栈不是一个东西&…

STM32F103C8T6第二天:按键点灯轮询法和中断法、RCC、电动车报警器(振动传感器、继电器、喇叭、433M无线接收发射模块)

1. 点亮LED灯详解(307.11) 标号一样的导线在物理上是连接在一起的。 将 PB8 或 PB9 拉低,就可以实现将对应的 LED 灯点亮。常用的GPIO HAL库函数: void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init);//I/…

DeepSORT多目标跟踪——算法流程与源码解析

一、目标检测与目标追踪 1. 目标检测 在目标检测任务中,主要目标是识别图像或视频帧中存在的物体的位置和类别信息。这意味着目标检测算法需要定位物体的边界框(Bounding Box)并确定每个边界框内的物体属于哪个类别(如人、汽车、…

SpringBoot-WebSocket浏览器-服务器双向通信

文章目录 WebSocket 介绍入门案例 WebSocket 介绍 WebSocket 是基于 TCP 的一种新的网络协议。它实现了浏览器与服务器全双工通信——浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输。 应用场景: 视…

基于 LangChain 构建 LLM 应用程序设计与实践

▼最近直播超级多,预约保你有收获 近期直播:《基 LangChain大模型架构案例实践》 —1— LangChain 是什么? LangChain 和 Semantic Kernel 是当前比较受欢迎的两款 LLM 应用开发框架。 LangChain 作为一个大语言模型应用开发框架,…

C++ 多态 纯干货讲解 复制可调试(1)

💯 博客内容:多态 😀 作  者:陈大大陈 🚀 个人简介:一个正在努力学技术的准C后端工程师,专注基础和实战分享 ,欢迎私信! 💖 欢迎大家:这里是CSD…

0007Java安卓程序设计-ssm基于Android的校园新闻管理系统

文章目录 **摘** **要**目 录开发环境 编程技术交流、源码分享、模板分享、网课教程 🐧裙:776871563 摘 要 网络的广泛应用给生活带来了十分的便利。所以把校园新闻管理与现在网络相结合,利用java技术建设校园新闻管理系统app,实…

【漏洞复现】Drupal_小于7.32版本 _“Drupalgeddon” SQL注入漏洞(CVE-2014-3704)

感谢互联网提供分享知识与智慧,在法治的社会里,请遵守有关法律法规 文章目录 1.1、漏洞描述1.2、漏洞等级1.3、影响版本1.4、漏洞复现1、基础环境2、漏洞扫描3、漏洞验证 说明内容漏洞编号CVE-2014-3704漏洞名称Drupal “Drupalgeddon” SQL注入漏洞漏洞…

搬家两年随笔

不知不觉中,我已经搬到这个地方两年多了。 回首这段时间,我感触颇深。 尽管这里地理位置较为偏僻,交通不是特别方便,但环境优美,绿树成荫,空气清新。 只是相对于之前的生活环境,这里离上班的地方…

【Linux】基本命令

和光同尘_我的个人主页 一直游到海水变蓝。 --余华 Linux基本命令 &#x1f56f;️前言基础指令lspwdcdtouchmkdirrmdirrmman**cp**mvcat**less指令**输出重定向 >追加重定向 >>输入重定向 <headtail&#xff08;查看日志常用&#xff09;管道时间相关指令dateca…

五:Day11_SpringMVC03

一、拦截器 SpringMVC给出了拦截器来实现单元方法的拦截&#xff0c;拦截器的执行是在DispatcherServlet之后和单元方法之前的。 注意&#xff1a;只有URL匹配到了控制单元&#xff0c;拦截器才能生效。 2. 使用拦截器 2.1 创建拦截器类 public class MyInterceptor implem…

S5PV210(十):LCD

本文主要探讨210的LCD相关知识。 LCD LCD称液晶(透光背光呈色),可在电信号驱动下使液晶分子旋转,呈现不同的颜色(被动发光) lcd接口为TTL接口(5V为1&#xff0c;0V为0),不能传输太远,远距离传输方式:SoC(TTL) ->VGA-> LCD(TTL) 其他显设备:CRT(…

Java基础篇 | 多线程详解

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a; Java从入门到精通 ✨特色专栏&#xf…

【数据结构】深入浅出讲解计数排序【图文详解,搞懂计数排序这一篇就够了】

计数排序 前言一、计数排序算法核心思路映射 概念补充绝对映射相对映射 二、计数排序算法核心实现步骤三、码源详解四、效率分析&#xff08;1&#xff09;时间复杂度 — O&#xff08;Max&#xff08;N&#xff0c;range&#xff09;&#xff09;&#xff08;2&#xff09;空间…

74HC138逻辑芯片

文章目录 74系列逻辑芯片——74HC138基础信息描述特征应用范围 功能信息封装引脚基本电路 扩展性能分析 74系列逻辑芯片——74HC138 基础信息 描述 74HC138器件设计用于需要极短传播延迟时间的高性能存储器解码或数据路由应用&#xff1b;在高性能存储系统中&#xff0c;可使用…

【C语言】扫雷游戏的一步一步的实现

文章目录 一、扫雷游戏分析和设计1.1 扫雷游戏的功能说明1.2 游戏的分析和设计1.2.1 数据结构的分析1.2.2 ⽂件结构设计 二、扫雷游戏代码实现总结 一、扫雷游戏分析和设计 1.1 扫雷游戏的功能说明 • 使⽤控制台实现经典的扫雷游戏 • 游戏可以通过菜单实现继续玩或者退出游…

时序分解 | Matlab实现EMD经验模态分解时间序列信号分解

时序分解 | Matlab实现EMD经验模态分解时间序列信号分解 目录 时序分解 | Matlab实现EMD经验模态分解时间序列信号分解效果一览基本介绍程序设计参考资料 效果一览 基本介绍 Matlab实现EMD经验模态分解时间序列信号分解 Matlab语言 算法新颖小众&#xff0c;用的人很少&#xf…