php字符串函数大全(php处理字符串函数)

什么是多字节的字符串操作呢?其实不少的同学可能都已经使用过了,但我们还是要从最基础的问题说起。一个字符占几个字节并不是我们表面上看到的那样。正常情况下,一个数字或英文以及英文符号都是占用一个字节的。但是这个世界的语言文字何其之多,特别是像中文、日文这

什么是多字节的字符串操作呢?其实不少的同学可能都已经使用过了,但我们还是要从最基础的问题说起。

一个字符占几个字节并不是我们表面上看到的那样。正常情况下,一个数字或英文以及英文符号都是占用一个字节的。但是这个世界的语言文字何其之多,特别是像中文、日文这样的文字,往往用一个字节装不下,这时候就需要多字节来解决了(多字节一般第一个字节是前导字节表示当前是什么语言文字,后面的是正被的字节编码)。比如说一个中文字在 GBK 环境是占用两个字节,而在 UTF-8 下则是占用三个字节。而在最近几年,由于 emoji 表情的出现 UTF-8MB4 又成为了主流,在表示这些 emoji 表情字符的时候,往往又会使用 UTF-8MB4 这种占用四个字节的编码格式来表示。

虽说字节的不同设置能够帮助我们展示丰富的内容,但对它的一些操作却也带来了麻烦。

字符串操作

$str = \"abc测试一下\";
echo strlen($str), PHP_EOL; // 15

strlen() 函数大家都不陌生,但是对于中文来说,它返回的数量明显是不对的。我们当前默认的编码格式是 UTF-8 ,所以将一个中文当做三个英文字符来数就正好是 15 个字符长度。很明显,这不是我们想要的结果,假设我们要截取字符串的话,这个长度的计算可是很费劲的,搞不好还容易出现乱码。

幸好在 PHP 的默认扩展中就已经为我们准备好了一组 mb_ 函数库,专门用来处理这类多字节字符串的问题。

echo mb_strlen($str), PHP_EOL; // 7
echo mb_strlen($str, \'GB2312\'), PHP_EOL; // 11

在不指定 mb_strlen() 函数的第二个参数的情况下,会按照当前文档的默认编码格式来进行转换,所以我们的字符串长度就在 UTF-8 的环境下正常显示了。当然,我们也可以指定第二个参数为其它的编码格式,比如以前常用的 GB2312 或者 GBK ,这样返回的字符长度就是以一个中文占两个字节的形式返回长度了。

var_dump(mb_strpos($str, \"测\")); // int(3)

var_dump(mb_convert_case($str, MB_CASE_UPPER)); // string(15) \"ABC测试一下\"
var_dump(mb_convert_case($str, MB_CASE_LOWER)); // string(15) \"abc测试一下\"

var_dump(mb_substr($str, 5)); // string(6) \"一下\"

当然,mb_ 相关的字符串操作函数是比较全面的,字符出现位置、大小写转换、截取字符串等函数都是提供的,调用的参数也都和普通的字符串操作函数没什么区别,只是它们多了一个可选的指定编码的参数。在通常的情况下,只要我们的文件是对应的编码格式,这个参数就不用去写了。

当然,字符串的操作函数还有很多,这里就不一一列举了,大家可以自行查阅相关的文档。

字符串正则操作

既然说到了字符串的操作,正则相关的功能也是必不可少的,我们先看下使用默认的 preg_ 相关的函数操作中文的问题。

$str = iconv(\'UTF-8\', \'GB2312\', $str);

var_dump(preg_match(\"/[a-z]*测试/i\", $str)); // int(0)
var_dump(preg_replace(\"/[a-z]*测试/i\",\"试试\", $str)); // string(11) \"abc����һ��\"

首先我们将测试用的字符串转换为 GB2312 的形式。就像我们获取的外部接口可能返回的就是 GB2312 的编码的。这时直接使用 preg_ 相关的函数是无法正确获得我们想要的结果的。

mb_regex_encoding(\'GB2312\');
$pattern = iconv(\'UTF-8\', \'GB2312\', \"[a-z]*测试\");
var_dump(mb_ereg($pattern, $str)); // int(1)
var_dump(mb_eregi($pattern, $str)); // int(1)

var_dump(mb_ereg_replace($pattern,\"试试\", $str)); // string(10) \"试试һ��\"
var_dump(mb_eregi_replace($pattern,\"试试\", $str)); // string(10) \"试试һ��\"

接下来我们通过 mb_ereg 相关的函数来进行正则的匹配和替换,就能正常的对不同编码的字符串进行操作了。注意,我们需要指定 mb_regex_encoding() 函数,告诉当前默认的规划替换编码是 GB2312 ,同时,正则规则也要转换成对应的编码格式。

mb_eregi 相关的函数和 mb_ereg 其实没有本质上的区别,只是它不区分大小写了,就像 preg 相关函数中我们写正则时的后缀符号 i 一样。ereg 相关的函数都是不用写反斜杠的,在普通的函数中其实是已经被淘汰了的函数(性能没有 preg 好,语法也有区别),大部分情况下都会直接使用 preg 相关的函数来进行操作。不过如果是牵涉到多字节相关的问题,在 mb_ 函数库中还是只有 ereg 这类的函数可以使用。

字符串编码转换

就像我们之前学习过的 iconv() 函数一样,mb_ 库中也提供了字符编码转换的函数。

$phone = file_get_contents(\'https://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=13888888888\');

print_r($phone);
// __GetZoneResult_ = {
// mts:\'1388888\',
// province:\'����\',
// catName:\'�й��ƶ�\',
// telString:\'13888888888\',
// areaVid:\'30515\',
// ispVid:\'3236139\',
// carrier:\'�����ƶ�\'
// }

var_dump(mb_convert_encoding($phone, \'UTF-8\', \"GBK\"));
// string(183) \"__GetZoneResult_ = {
// mts:\'1388888\',
// province:\'云南\',
// catName:\'中国移动\',
// telString:\'13888888888\',
// areaVid:\'30515\',
// ispVid:\'3236139\',
// carrier:\'云南移动\'
// }
// \"

echo mb_detect_encoding($phone, \'UTF-8,GBK\'), PHP_EOL; // CP936

同样我们还是拿这个获取手机号信息的公共接口测试,它返回的内容是 GBK 的编码内容。我们可以通过 mb_convert_encoding() 来转换它的编码内容。mb_detect_encoding() 是检测编码格式,这里我们给了两个参数,它会返回符合条件的编码内容,CP936 就是 GBK 的另一种表示(IBM在制作 code page 时将 GBK 编码放在了第 936 页)。

HTTP 参数操作

mb_internal_encoding(\"UTF-8\");

首先介绍一个 mb_internal_encoding() 函数,其实就是设置当前运行环境中的默认编码规则的,如果不设置的话,就是以当前这个 php 文件的编码规则为默认的。大家了解一下,因为它会影响我们后面介绍的内容。

// // localhost:9991/?a=我上
var_dump(mb_http_input(\'GPC\')); // bool(false)
var_dump(mb_http_output()); // string(5) \"UTF-8\"

mb_internal_encoding(\"CP936\");
mb_parse_str($_SERVER[\'QUERY_STRING\'], $result);
print_r($result);
// Array
// (
// [a] => 我上
// )

首先我们运行起来测试文件,然后用浏览器请求这个链接地址。mb_http_input() 是检测 HTTP 输入字符编码,不过我测试的结果都是返回 false 。有了解的小伙伴可以留言说明下这个是什么情况。而 mb_http_output 则是设置检测输出的编码,这个就会受到 mb_internal_encoding() 所定义的内容的影响。

另外,mb_parse_str() 是 parse_str() 函数的多字节版,我们可以将浏览器的默认编码转换成 GBK 或者 之后再来请求,因为我们设置当前的 mb_internal_encoding() 为 CP936 了。在默认情况下,如果使用 UTF-8 的浏览器请求的话,这里就会报错了,这就是 mb_internal_encoding() 对这些函数的影响。

其它属性查看

最后,我们再来看看一些 mb_ 相关信息属性的内容。

var_dump(mb_language());
// string(7) \"neutral\"

mb_language() 函数用于获取/设置当前的语言,它可以接收一个参数设置当前的语言信息。主要用于编码邮件信息 mb_send_mail() 函数就是使用它来对邮件进行编码。关于 mb_send_mail() 的使用大家可以自己尝试一下,其实也是 send_mail() 函数的多字节版。neutral 的意思是中立的,其实也是跟我们的 mb_internal_encoding() 有关。

var_dump(mb_list_encodings());
// array(86) {
// [0]=>
// string(4) \"pass\"
// [1]=>
// string(5) \"wchar\"
// [2]=>
// string(7) \"byte2be\"
// [3]=>
// ……
// [65]=>
// string(5) \"CP936\"
// ……

mb_list_encodings() 用于展示当前系统中所支持的所有语言编码的列表,在这个列表中我们就可以看到 CP936 的身影,但是没有 GBK 哦,记住它们俩是一个东西就好了。

var_dump(mb_get_info());
// array(14) {
// [\"internal_encoding\"]=>
// string(5) \"UTF-8\"
// [\"http_output\"]=>
// string(5) \"UTF-8\"
// [\"http_output_conv_mimetypes\"]=>
// string(31) \"^(text/|application/xhtml\\+xml)\"
// [\"func_overload\"]=>
// int(0)
// [\"func_overload_list\"]=>
// string(11) \"no overload\"
// [\"mail_charset\"]=>
// string(5) \"UTF-8\"
// [\"mail_header_encoding\"]=>
// string(6) \"BASE64\"
// [\"mail_body_encoding\"]=>
// string(6) \"BASE64\"
// [\"illegal_chars\"]=>
// int(0)
// [\"encoding_translation\"]=>
// string(3) \"Off\"
// [\"language\"]=>
// string(7) \"neutral\"
// [\"detect_order\"]=>
// array(2) {
// [0]=>
// string(5) \"ASCII\"
// [1]=>
// string(5) \"UTF-8\"
// }
// [\"substitute_character\"]=>
// int(63)
// [\"strict_detection\"]=>
// string(3) \"Off\"
// }

mb_get_info() 是查看当前环境下默认的这些语言编码的配置,比如我们熟悉的 internal_encoding 、 http_output 属性都能在这里看到。

总结

用过的同学是不是也发现了今天文章的新姿势了呢?没错,GBK 和 CP936 反而成为了今天文章的意外惊喜。这个在之前确实还真没有注意到。其实 mb_ 相关的函数的使用已经非常普遍了,基本算是学习 PHP 的入门必备知识了。它还有很多的函数并没有一一地列举出来,有兴趣的同学可以多多查阅官方手册进行更加深入地学习。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请发送邮件至 55@qq.com 举报,一经查实,本站将立刻删除。转转请注明出处:https://www.szhjjp.com/n/25246.html

(0)
nan
上一篇 2021-09-14
下一篇 2021-09-14

相关推荐

  • 职工工伤伤残等级鉴定申请书(工伤鉴定申请书)

    申请人:XXX,男,汉族,XXX年XX月XX日出生,住XXX,身份证号码XxX被申请人:XXX公司,住所XXX,统一社会信用代码XXX法定代表人:XXXX,该公司经理请求事项1、请求裁决解除申请人与申请人之间的劳动合同(劳动关系)。

    2021-12-12
    0
  • 如何注册edu域名(edu域名怎么注册)

    如何注册edu域名,edu域名怎么注册内容导航:请问edu教育网站的域名怎么申请如何注册域名edu域名是什么什么是域名注册呢一、请问edu教育网站的域名怎么申请中国教育和科研计算机网网络域名注册办法[CERNIC-020-CN]CERNET网络信息中心/1997年6月制订2002年9月修订1997年6月3日,国务院信息化工作领导小组办公室宣布中国互联网信息中

    2022-05-08
    0
  • Prometheus监控的优点有哪些

    实时监控:Prometheus能够实时监控系统的各种指标,可以及时发现系统出现的问题。灵活性高:Prometheus支持多种监控方式,可以监控多种不同类型的指标。便于扩展:Prometheus的数据模型简单且灵活,容易扩展和定制。高度可视化:Prometheus的监控数据可以通过Grafana等可视化工具展示,让用户更直观地了解系统的运行状态。警报功能:Prometheus支持设置警报规则,当系统

    2024-03-19
    0
  • 如何在Ubuntu中挂载外部驱动器

    在Ubuntu中挂载外部驱动器可以通过以下步骤进行:首先插入外部驱动器到计算机的USB端口中。打开终端窗口(Ctrl + Alt + T)。运行以下命令来查看系统中已连接的设备列表:lsblk根据输出的信息找到你要挂载的外部驱动器,通常会以类似于 /dev/sdX 的形式显示(X为字母,代表具体的设备)。创建一个目录用来挂载外部驱动器。比如,运行以下命令创建一个名为 external_drive

    2024-04-01
    0
  • c++多态实现的三种形式是什么

    C++实现多态的三种形式是:静态多态性(早绑定):使用函数重载和运算符重载实现,编译器在编译时确定调用的函数或运算符。动态多态性(晚绑定):使用虚函数和指针/引用实现,运行时根据对象的实际类型确定调用的函数。纯虚函数和抽象类:通过将虚函数声明为纯虚函数,将类定义为抽象类,实现接口的统一定义,子类必须实现纯虚函数才能实例化。

    2024-01-27
    0
  • Redis怎么与Python集成使用

    要在Python中使用Redis,首先需要安装Redis的Python客户端库。常用的Python Redis客户端包括redis-py和hiredis。以下是使用redis-py库与Redis集成的示例代码:安装redis-py库:pip install redis连接到Redis服务器:import redis# 创建Redis连接r = redis.Redis(host='lo

    2024-05-07
    0

发表回复

登录后才能评论