谈谈不换行空格

简介:

昨天工作中遇到了一个问题问题:php程序从数据库中取出变量 a " c a r w s " i c o n v u t f 8 g b 2312 b,结果判断语句 a == b 竟然是false!

究其原因原来是这里的空格是不换行空格。

什么是不换行空格?

不换行空格(non-blocking space)也是一种空格,它和普通空格的区别在于在排版的时候表现不同。比如在word中,下面一段话在“如果它”三个字中间有两个空格,第一段是使用普通空格的排版表现,第二段是使用不换行空格(word中输入不换行空格使用ctrl+shift+space)的排版表现。

Image(2)

第一段中“如”和“果”字中间的空格就被换行了,而第二段中的“如果它”三个字中的不换行空格就像是告诉word:这三个字是连在一起的,你如果要进行换行,就把我们一起进行换行,不能从中间隔断~所以谓之“不换行空格”。

在html中也有不换行空格的概念,&nbsp(本身就是non-blocking space的缩写)。在html中使用&nbsp也能达到不换行的目的,比如下面这个例子:

Image(3)

文字中的“排版时”三个字中间有空格,第一段使用普通空格,第二段使用&nbsp(html字符集中的non-blocking),第三段使用UTF-8字符集中的non-blocking space(我是直接从word中复制出来的,sublime text中如何输入non-blocking space没查出来,有知道的麻烦告诉一下)

在浏览器下显示情况:

Image(4)

之所以这么表现的原因和word中是一样的。

在HTML中,页面会合并多个连续的空格,而不换行空格是禁止合并的,因此它也称为“硬空格”,“固定空格”。

不同编码中的不换行空格

在不同编码下的不换行空格有不同的值设定,比如

在UTF8中,值为0xC2,0xA0(所以使用urlencode编码不换行空格会显示%c2%a0)

在HTML中,值为&nbsp,或者&#160(可以参考HTML特殊字符对照表http://www.jb51.net/onlineread/htmlchar.htm)

下图是不换行空格在不同字符集的表示

Image(5)

编码转换中的损失

从上张表中可以看出,最大的问题就是不换行空格并不是在所有编码中都存在,比如在我们经常使用到的GBK,GB2312,GB18032中都是没有不换行空格的。于是在字符转码中就会遇到问题了,主要归结于从一个有不换行空格的编码转换到没有不换行空格的编码的时候,程序会怎么处理这个不换行空格?

在php中,看下面这个程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
$normalspace  = " " ;
$nonblockingspace  = " " ;
echo  urlencode( $normalspace ), PHP_EOL;
echo  urlencode( $nonblockingspace ), PHP_EOL;
 
$normalspace_gb2312  = iconv( "UTF-8" , "GB2312" , $normalspace );
$nonblockingspace_gb2312  = iconv( "UTF-8" , "GB2312" , $nonblockingspace );
 
echo  urlencode( $normalspace_gb2312 ), PHP_EOL;
echo  urlencode( $nonblockingspace_gb2312 ), PHP_EOL;
 
$normalspace_gb2312_2  = iconv( "UTF-8" , "GB2312//TRANSLIT" , $normalspace );
$nonblockingspace_gb2312_2  = iconv( "UTF-8" , "GB2312//TRANSLIT" , $nonblockingspace );
 
echo  urlencode( $normalspace_gb2312_2 ), PHP_EOL;
echo  urlencode( $nonblockingspace_gb2312_2 ), PHP_EOL;

(其中的nonblockingspace是不换行空格,在vim中是使用ctrl +k, shift +N, shift +S打出来的)

输出:

Image(6)

在iconv的out_charset不加//IGNORE或者//TRANSLIT的情况下出现的Notice就是提示说这里的 n o n b l o c k i n g s p a c e G B 2312 i c o n v nonblockingspace_gb2312 是空字符串。

而iconv加上了//TRANSLIT之后,php程序会去GB2312字符集中寻找和不换行空格最相近的一个字符(也就是空格),因此$nonblockingspace_gb2312_2是普通空格。

解决问题

到这里最初的问题就完全可以理解了

php程序从数据库中取出变量 a " c a r w s " i c o n v u t f 8 g b 2312 b,结果判断语句 a == b 竟然是false!

 

首先我的数据库一定是支持不换行空格的字符集(我的数据库是UTF-8编码的)在库中存的变量 a c a r [ ] w s a后中间就带有了不换行空格,再经过iconv转换后,不管是使用//IGNORE,//TRANSLIT,还是不做任何处理,它们两个都不可能是相等的了。

于是就知道了解决办法,在转码之前先做一次replace操作,否则转码后就是不可逆的了。

a = s t r r e p l a c e ( "" , "" , a);

 

于是我和我的小朋友们不用再郁闷了。






本文转自轩脉刃博客园博客,原文链接:http://www.cnblogs.com/yjf512/p/3216392.html,如需转载请自行联系原作者

相关文章
EndNote参考文献显示中国作者名的第二个字的首字母的方法
本文介绍利用EndNote软件,对论文参考文献中英文文献的汉语拼音姓名(即含有中国作者的英文论文)的名的第二个字的首写字母加以补充显示~
635 1
EndNote参考文献显示中国作者名的第二个字的首字母的方法
|
存储 开发工具
Emacs+SBCL+Slime+CHLS(QuickLisp)
Emacs+Slime+CHLS(QuickLisp)
389 7
|
JSON API 数据格式
Postman 导入导出API 的用法
大家好,我是阿萨。昨天学习了如何使用Postman里的collections?关于API 脚本的最基本场景我们就学习完成了。 日常工作中会碰到各种各样的情况需要导入或者导出API。
1333 0
Postman 导入导出API 的用法
|
9月前
|
数据采集 Web App开发 监控
Puppeteer代理认证的最佳实践和示例
Puppeteer代理认证的最佳实践和示例
字符编码问题之GB2312编码扩充到包括更多汉字和生僻字的如何解决
字符编码问题之GB2312编码扩充到包括更多汉字和生僻字的如何解决
258 0
|
机器学习/深度学习 存储 自然语言处理
基于知识库快速搭建智能客服问答 Bot
在数字化转型的大潮中,智能客服系统成为提升企业客户体验与运营效率的关键工具。Botnow平台集成智能体创作与分发功能,提供一站式智能客服问答Bot搭建服务。本文详细介绍了如何利用Botnow的知识库功能及RAG(Retrieve-Augmented Generation)方案快速构建智能客服问答Bot。通过Botnow平台,用户可以轻松创建知识库、配置智能体,并关联知识库以实现智能回答。该方案广泛适用于对话沟通、行业知识库建设、企业内部信息检索及内容创作等多个场景。Botnow平台以其可视化编排、低技术门槛等特点,助力企业轻松实现智能客服系统的搭建与优化,成为数字化转型的重要推手。
820 1
|
XML JSON Java
经验大分享:SpringCloud之Feign
经验大分享:SpringCloud之Feign
250 0
|
人工智能 算法
直接使用大模型面临的问题
【1月更文挑战第20天】直接使用大模型面临的问题
743 4
直接使用大模型面临的问题
|
API 开发者
1688阿里巴巴中国站平台 API接口获取商品详情 接入文档说明
1688(阿里巴巴批发网)的API接入文档是专为开发者提供的,用于指导如何集成和使用1688平台提供的API接口。这些API接口可以帮助开发者实现各种功能,如商品搜索、订单管理、用户认证等。
|
Web App开发 存储 前端开发
【4万字长文吐血整理】LaTeX基础使用【助你熟练玩转LaTeX】
【4万字长文吐血整理】LaTeX基础使用【助你熟练玩转LaTeX】