第 3 章 字符串和数组操作
第 2 章初步介绍了 PHP 的数据类型,本章将详细地介绍其中的字符串和数组的操作。
3.1 操作字符串
在 Web 应用中,用户和系统的交互基本上是用文字来进行的,因此系统对文本信息,即字
符串的处理非常重要。文本字符串操作内容很多,本节将对其一一介绍。
3.1.1 去除空格和其他特殊符号
有时,需要去掉字符串中的空格或者其他没有意义的符号。例如,在一个电子商务应用中,
当用户填写订单的内容时(如联系地址),可能输入一些空格、句号等字符,系统希望在存
储之前把它们去掉,只剩下干净有意义的信息。为了完成类似于上述需求的问题,PHP4 及
以上版本提供了 4 个去除字符串中特殊符号的函数:
string trim ( string str [, string charlist]) :去除字符串 str 首尾处空格或其他特殊符号;
string ltrim ( string str [, string charlist]) :去除字符串 str 首的空格或其他特殊符号;
string rtrim ( string str [, string charlist]):去除字符串 str 尾的空格或其他特殊符号;
string chop ( string str [, string charlist]):同 rtrim()。
以上函数的第一个参数 str 为待操作的字符串,第二个可选参数 charlist 指定想要去除的特殊
符号,当缺省时默认值为去掉下列字符:空格(" ")、制表符(\t)、换行符(\n)、回车符(\r)、
空值(\0)。还可以使用“..”在通过第二个参数指定需要去除一个范围内的字符,例如“a..d”
指去掉 ASCII 码值介于 a 和 d 之间的字符,即 a、b、c、d。
下面以 trim()为例说明上述函数的使用:
";
$trimmed_str = trim($init_str);
echo $trimmed_str."#
";
$trimmed_str = trim($init_str,', .');//"山东省济南市经十路 8 号 1"。注意,第二个参数包括
//"山东省济南市经十路 8 号 1."
1
2
3
4
5
6
7
三个字符。
8
9
数字字符
10
11 ?>
echo $trimmed_str."#
";
$trimmed_str = trim($init_str,', .0..9'); //"山东省济南市经十路 8 号"。0..9 说明要去掉所有的
echo $trimmed_str."#
";
第 3 行定义了一个字符串变量,在其首部有空格和逗号,其尾有句号和空格;
第 5 行使用不带第二个参数的 trim()函数去掉了其中首尾处的空格符号;
第 7 行使用带有第二个参数的 trim()函数去掉了其首尾处的第二个参数中所包含的字符,即
去掉了首尾处的空格、逗号和句号。
第 9 行 trim()中第二个参数中的“0..9”说明将要去掉这个位于 0 和 9 的 ASC 码范围内的所
有字符。
ltrim()、rtrim()的使用同 trim()类似,而 chop()实际上是 rtrim()的别名,其功能与 rtrim()一样,
不再赘述。
3.1.2 加入和去除反斜杠
在许多应用中,例如生成 SQL 语句时(SQL 语句将在第二部分中介绍),需要在其中加入转
义字符‘\’,手工构造起来相当麻烦。为了解决类似问题,PHP 提供了自动在字符串中加入
或去除转义字符的函数:
string addcslashes ( string str, string charlist):第一个参数 str 为待操作的原始字符串,第
二个参数 charlist 说明需要在原始串的那一些字符前加上字符‘\’。
string stripcslashes ( string str) :去掉字符串中的‘\’。
二者的使用参考下面代码:
1
2
3
4
5
6
7
8
9
";
$new_str = addcslashes($init_str,"'");
echo $new_str."#
";
$init_str2 = stripcslashes($new_str);
echo $init_str2."#
";
?>
代码在第 5 行在$init_str 中的‘’’前加上了‘\’,又在第 9 行将其去掉。
3.1.3 生成 HTML 元素
HTML 元素的书写非常麻烦,下面简单列出一些常用字符在在 HTML 中的表示方式。
'&':'&'
双引号‘"’:'"'
单引号‘'’:'''
'<' :'<'
'>' :'>'
此处,称'&'等为 HTML 元素,'&'等为其显示字符串。例如,若想在页面上的显示 “
链接”,HTML 应写为“<a href='test'>Test</a>”,否则,
将只在页面上显示一个链接信息。
PHP 提供了下面的函数来自动转化 HTML 元素:
string htmlspecialchars ( string str [, int quote_style [, string charset]]):把一些常用的 HTML
元素转换为显示字符串;
string htmlentities ( string str [, int quote_style [, string charset]]):把所有的 HTML 元素转
换为显示字符串;
string html_entity_decode ( string str [, int quote_style [, string charset]]):把显示字符串转化
为 HTML 元素。
上面函数中,参数 str 表示原始字符串;可选参数 quote_style 确定是否转换双引号和单引号,
取值范围为{ ENT_COMPAT , ENT_QUOTES , ENT_NOQUOTES},分别表示只转换双引号、
全转换、全不转换,缺省时默认值为 ENT_COMPAT;第三个参数 charset 指定了转换中所用
的字符集。PHP4 及以上版本所支持的字符集参考表 3.1。
表 3.1 PHP4 及以上版本支持的字符集
说明
西欧字符集
西欧字符集扩展
兼容ASCII的宽字节字符集
西欧字符集,Windows系统默认
繁体中文,用于中国台湾省
简体中文,用于中国大陆
字符集
ISO-8859-1
ISO-8859-15
UTF-8
cp1252
BIG5
GB2312
BIG5-HKSCS 繁体中文扩展,用于中国香港
Shift_JIS
EUCJP
日文
日文
下面的示例中,首先使用 htmlentities()函数得到一个 HTML 语句的显示字符串,然后再用
html_entity_decode()函数重新把显示字符串转回 HTML 元素。运行结果如图 3.1 所示。
1
2
3
4
5
6
7
8
学习! ";
$a = htmlentities($orig,ENT_COMPAT,"GB2312");
$b = html_entity_decode($a);
echo $a; // I'll "walk" the <b>dog</b> now
echo $b; // I'll "walk" the dog now
?>
图 3.1 PHP 生成 HTML 元素示例
注意:函数 html_entity_decode()只支持 PHP4.0.3 及以上版本。
除 上 面 所 提 到 的 三 个 函 数 之 外 , 用 于 HTML 元 素 操 作 的 函 数 还 包 括 nl2br() 、
get_html_translation_table()等,功能与上述函数类似,本书不再一一详述。
3.1.4 分解字符串
分 解 字 符 串是 指 把 一 个字 符 串 通 过特 殊 的 符 号分 解 为 许 多子 串 。 例 如, 时 间 字 符串
“2005-01-01 12:59:59”可以利用符号“-”、空格和“:”分解为年月日时分秒具体的值。PHP
提供了下列函数完成类似功能:
array split ( string pattern, string str [, int limit]);
其中,参数 pattern 指定了作为分解标识的符号;str 为待操作的原始串;第三个可选参数 limit
为返回子串个数的最大值,缺省时为全部返回。函数的返回值为数组,将在 3.2 节对其进行
介绍。此处,可以暂时把函数返回值理解为多个子串即可。
下面的示例可以把字符串“2005-01-01 12:59:59”分解为年月日时分秒子串:
1
2
3
4
5
\n";
6
?>
上例将输出“2005 年 01 月 01 日 12 时 59}分 59 秒”。第 4 行使用 split 函数把时间分解,分
解的标识符包括“-”、空格和“:”,在第 5 行将其输出。
除 split 之外,功能相似的函数还包括 preg_split(),explode(),implode(),chunk_split()和
wordwrap()等。
3.1.5 格式化字符串
格式化字符串用于按一定的格式输出含有许多变量的文本,是最常用的一种操作。PHP 的
fprintf()函数完成这个功能,习惯使用 C 语言的读者肯定对其感到熟悉。函数原型为:
string sprintf(string format, mixed [args]...);
参数 format 是转换后的格式,各个变量都以“%”后的字符规定其格式,后面的多个参数以
此对应于 format 中的“%”处。下面示例格式化浮点数的小数部分。
$name="张三";
$money1 = 68.75;
$money2 = 54.35;
$money = $money1 + $money2;
// 此时变数 $money 值为 "123.1";
$formatted = sprintf ("%s 有¥%01.2f。",$name, $money);
echo $formatted;
//张三有¥123.10。
1
2
3
4
5
6
7
8
9
10 ?>
第 6 行通过算术运算,得到$money 的值为 123.1;而在第 8 行通过 sprintf 中的%01.2 定义其
格式为显示小数点后两位。
除 sprintf()之外,常用于格式化数据的函数还有 printf()、sprintf()、sscanf()、fscanf()、vsprintf()、
number_format()等。
3.1.6 获取和替换子串
获取子串是指对从一个串中获取其中连续的一部分。例如,从串“2005-01-01 12:59:59”中
取得时间串。PHP 提供了两个函数来获取或替换串的某一部分:
string substr ( string str, int start [, int length]) :获取子串,第一个参数 str 是待操作的串,
第二个参数 start 表明子串在总串中的起始位置,第三个可选参数指定所获取的子串
长度,如果为正数则表明子串从 start 向右取,否则向左取;缺省时默认值为从 start
取到串尾。
string substr_replace ( string str, string replacement, int start [, int length]) :在获取的基础上
进行替换,即将获取出的子串替换为其第二个参数 replacement。
下面的示例中,首先利用 substr()获取串“2005-01-01 12:59:59”的时间信息,然后使用
substr_replace()函数将年份信息改为“2006”:
1
2
3
4
5
6
7
8
?>
$date = "2005-01-01 12:59:59";
$time=substr($date,11,8); //子串"12:59:59"的起始位置为 11,长度为 8
echo "time:$time
";
$new_date=substr_replace($date,"2006",0,4);
echo "new date:$new_date";
3.1.7 定位字符
定位字符是指寻找某个字符在串中最先出现的位置,函数 strpos()可以完成此功能:
int strpos ( string str, char needle):第一个参数 str 为待处理的串,第二个参数 needle 为待
寻找的字符。下面这个示例,对一个电子邮件地址进行处理,首先使用 strpos()寻找
字符“@”,然后结合获取子串函数 strstr()获取用户名。
?>
$email = "zhangsan@php.net";
$i=strpos($email,'@');
$name=substr($email,0,$i);
echo $name;
1
2
3
4
5
6
7
示例第 4 行使用 strpos()获取了字符’@’的位置,然后在第 5 行使用 substr()得到用户名子串
信息。
3.1.8 求串长度
求串长度也是常用的操作,所使用的函数为 strlen():int strlen ( string str)。
这个函数很简单,返回字符串 str 的长度。仍以上一小节的例子为例,从电子邮件串中替换
用户的名字,即改为“lisi@php.net”:
1
2
3
4
5
6
7
8
?>
$email = "zhangsan@php.net";
$i=strpos($email,'@');
$name=substr($email,0,$i);
$email=substr_replace($email,"lisi",0,strlen($name));
echo $email;
3.1.9 获取 ASCII 编码
把字符转化为 ASCII 编码在实际应用中有时是很有用的,例如,字符串在数据库中以二进
制形式存放,而需要数据获取函数返回 ASCII 码串时,就需要把其转化为字符串显示。PHP
提供的转换 ASCII 码和字符的函数有:
string chr ( int ascii):把 ASCII 码转化为字符串;
int ord ( string string):把字符串转化为 ASCII 码。
二者的使用参考下例:
1
2
3
4
5
6
7
?>
$letter = chr(65);
$ascii=ord('A');
echo $letter;
echo $ascii;
//A
//65
3.1.10 比较字符串
字符串的比较规则是按照字典排序方法,排在前面的小于后面的。如同在一本英语词典中,
后面的词条大于前面的词条。PHP 实现字符串比较的函数为:
int strncmp ( string str1, string str2[, int len]):函数的前两个参数为待比较的两个字符串,
第三个可选参数可指定想比较二者从头开始的多少个字符。如果 str1>str2,函数返
回正数;str1=str2 时返回 0;str1
?>
$str1="China";
$str2="Beijing";
$i=strcmp($str1,$str2);
echo $i;
//1
除 strcmp()之外,具有字符串比较或排序功能的函数还 strcasecmp(),strncmp(),strncasecmp(),
strnatcasecmp(),strstr(),natsort()andnatcasesort()。
3.1.11 大小写转换
当比较两个字符串是否在不区分大小写时相等时,仅仅使用上一小节的 strcmp()函数就不行
了,这时可将两个字符串同时转换为大写或小写,然后再进行比较即可。例如,在判断网站
登录的用户名和密码(不区分大小写时)时,常需要这样。PHP 实现字符串大小写转换的
函数有:
string strtolower ( string str) :将 str 转换为小写形式;
string strtoupper ( string string) :将 str 转换为大写形式;
string ucfirst ( string str) :将 str 的第一个字符转换为大写形式;
string ucwords ( string str) :将 str 中每一个单词的首字母转换为大写形式。
参考下例:
$str1="shandong province";
$str2="China";
$str1=ucwords($str1);
echo $str1;
$str1=strtoupper($str1);
echo $str1;
$str2=strtolower($str2);
echo $str2;
//china
1
2
3
4
5
6
7
8
9
10
11 ?>
//Shangdong Province
//SHANGDONG PROVINCE
3.1.12 小结
字符串是 PHP 中应用最为广泛的数据类型,其操作也种类繁多。PHP4 及以上版本提供了五
十多个内置的字符串操作函数,熟练的使用这些函数,是使用 PHP 的重要内容。本节介绍
了其中最为常用的大部分函数,其余未能涉及的部分,请读者在开发或学习过程中参考 PHP
函数手册。
3.2 正则表达式
正则表达式是一个非常大的题目 PHP 继承了 Perl 的正则表达式法则,还有自己的一套法则。
本节将详细介绍 PHP 的正则表达式。
3.2.1 理解正则表达式
正则表达式是一种可以用于模式匹配的强大工具。简单地说,正则表达式就是一套规则,用
于去判定其他的元素是否符合它。
举一个简单的例子:在一个用户注册的页面中(例如,一个论坛或者交友网站的注册页面),
上面可能有“电子邮件”这一项需要填写。对系统来说,需要判定用户所填写的电子邮件地
址是否合法,即是否符合电子邮件地址的规则。利用上一节介绍的字符串操作技术可以来实
现这个功能:
//检查是否包含@
//检查是否包含.
return 0;
//true
//false
上面代码实现了一个函数 validate_email1(),使用字符串操作中的定位字符函数,用来判断
一个字符串是否是一个合法的电子邮件地址。仔细考虑实现的功能,实际上是在判断一个字
符串是否具有一定的模式,或者说是否满足一定的规则。在这种情况下,就可以使用正则表
达式来实现相同的功能:
1
2
3
4
5
6
7
8
9
//true
//false
上面实现了具有相同功能的函数 validate_email1(),函数使用了一个正则表达式的函数
ereg(),其具体使用将在下一节介绍。
观察 ereg()函数的参数“^[a-zA-Z]+@[a-zA-Z]+\.[a-zA-Z]+$”,容易看出其实际上表示满足这
样规则的字符串:以[a-zA-Z]即任意大小写字符串开头,然后紧跟“@”,然后又是任意大小
写字母组成的字符串,第四部分是符号“.”,最后仍是任意字符串。这相当于定义了一个字
符串的组成规则。
在看过这个示例后,重新来看正则表达式的定义:正则表达式是一种可以用于模式匹配的强
大工具。
3.2.2 使用正则表达式
在 PHP 有六个函数来处理正则表达式,用来检查一个字符串是否满足一个的规则。它们都
把一个正则表达式作为它们的第一个参数,语法为:
bool ereg ( string pattern, string string [, array regs]):最常用的正则表达式函数, 搜索跟正
则表达式 pattern 匹配的一个字符串。搜索到返回 true,否则返回 false。
string ereg_replace ( string pattern, string replacement, string string) :搜索跟正则表达式
pattern 匹配的一个字符串,并用新的字符串代替所有这个表达式出现的地方。
bool eregi ( string pattern, string string [, array regs]) :和 ereg 几乎是一样效果,不过忽略
大小写。
string eregi_replace ( string pattern, string replacement, string string) :和 ereg_replace 有着
一样的搜索-替换功能,不过忽略大小写。
array split ( string pattern, string string [, int limit]) :搜索和正则表达式匹配的字符串,并
且以字符串集合的方式返回匹配结果。
array spliti ( string pattern, string string [, int limit]) :同 split 一样,不过忽略大小写。
本节,旨在给出 PHP 提供的正则表达式函数,并简单介绍其功能。对于上述函数的具体使
用,则要在首先了解了正则表达式的构造之后才能介绍。
3.2.3 构造正则表达式
如前所述,在匹配一个字符串到正则表达式之前,必须先构造正则表达式。
1.定义头部规则
PHP 用“^”定义字符串头部的规则,例如:“^hello”即定义头部为“hello”的字符串,结
合上一节所介绍的函数,代码
将返回“true”,因为待验证的字符串“hello word!”满足规则:以“hello”开头。而
将返回 false,因为 hello 不在字符串”I say hello world”的头部。
2.定义尾部规则
//false
//true
PHP 用“$”定义字符串尾的规则,例如:“world$”即定义尾部为“world”的字符串,代
码
将返回“true”,因为待验证的字符串“hello word!”满足规则:以“world”结尾。而
将返回 false,因为 world 不在字符串”I say hello php”的尾部。
3.定义包含任意字符规则
//false
//true
PHP 用“.”定义包含任意字符的规则,例如:“.”即定义包含任意字符的字符串,代码
将返回“true”,因为待验证的字符串“something”满足规则:包含任意字符。而
//true