Golang 的字符编码与 regexp 原创

本文探讨了在Golang中使用regexp处理网络流量时遇到的匹配问题,原因是regexp内部以UTF-8编码处理,而网络流量通常为字节序列。通过分析UTF-8编码和Golang的字符类型,提出了解决方法,即在匹配前将字符串转换为合法的UTF-8格式。
摘要由CSDN通过智能技术生成

前言

最近在使用 Golang 的 regexp 对网络流量做正则匹配时,发现有些情况无法正确进行匹配,找到资料发现 regexp 内部以 UTF-8 编码的方式来处理正则表达式,而网络流量是字节序列,由其中的非 UTF-8 字符造成的问题。

我们这里从 Golang 的字符编码和 regexp 处理机制开始学习和分析问题,并寻找一个有效且比较通用的解决方法,本文对此进行记录。

本文代码测试环境 go version go1.14.2 darwin/amd64

regexp匹配字节序列

我们将匹配网络流量所遇到的问题,进行抽象和最小化复现,如下:

我们可以看到 \xff 没有按照预期被匹配到,那么问题出在哪里呢?

UTF-8编码

翻阅 Golang 的资料,我们知道 Golang 的源码采用 UTF-8 编码, regexp 库的正则表达式也是采用 UTF-8 进行解析编译(而且 Golang 的作者也是 UTF-8 的作者),那我们先来看看 UTF-8 编码规范。

1.ASCII在计算机的世界,字符最终都由二进制来存储,标准 ASCII 编码使用一个字节(低7位),所以只能表示 127 个字符,而不同国家有不同的字符,所以建立了自己的编码规范,当不同国家相互通信的时候,由于编码规范不同,就会造成乱码问题。

“中文”

GB2312: \xd6\xd0\xce\xc4
ASCII: ???? 

2.Unicode为了解决乱码问题,提出了 Unicode 字符集,为所有字符分配一个独一无二的编码,随着 Unicode 的发展,不断添加新的字符,目前最新的 Unicode 采用 UCS-4(Unicode-32) 标准,也就是使用 4 字节(32位) 来进行编码,理论上可以涵盖所有字符。

但是 Unicode 只是字符集,没有考虑计算机中的使用和存储问题,比如:

1.与已存在的 ASCII 编码不兼容,ASCII(A)=65 / UCS-2(A)=0065

2.由于 Unicode 编码高字节可能为 0,C 语言字符串串函数将出现 00 截断问题

3.从全世界来看原来 ASCII 的字符串使用得最多,而换成 Unicode 过后,这些 ASCII 字符的存储都将额外占用字节(存储0x00)

3.UTF-8后来提出了 UTF-8 编码方案,UTF-8 是在互联网上使用最广的一种 Unicode 的实现方式;UTF-8 是一种变长的编码方式,编码规则如下:

1.对于单字节的符号,字节的第一位设为 0,后面 7 位为这个符号的 Unicode 的码点,兼容 ASCII

2.对于需要 n 字节来表示的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值