4.7 处理和查找字符串
Manipulating and Searching Strings
PHP有许多函数用于操作字符串。查找和修改字符串最常用的函数是用正则表达式来描述字符串的函数。本节介绍的函数没有使用正则表达式——它们比正则表达式快,但是它们只能用于查找确定的字符串(例如,你在查找"12/11/01",而不是"任何用斜杆分隔的数字")。
4.7.1 子串
Substrings
你想知道在一个较大字符串中你感兴趣的数据的位置,可以使用substr( )函数把它复制出来:
$piece = substr(string, start [, length ]);
start 参数是在string 中要开始复制的位置,如果是0的话,就是说从字符串开头开始复制。length 参数是要复制字符的个数(默认是复制到字符串末尾)。例如:
$name = "Fred Flintstone";
$fluff = substr($name, 6, 4); // $fluff 是 "lint"
$sound = substr($name, 11); // $sound 是 "tone"
要知道一个小字符串在一个大字符串中出现的次数,可以使用substr_count()函数:
$number = substr_count(big_string, small_string);
例如:
$sketch = <<< End_of_Sketch
Well, there's egg and bacon; egg sausage and bacon; egg and spam;
egg bacon and spam; egg bacon sausage and spam; spam bacon sausage
and spam; spam egg spam spam bacon and spam; spam sausage spam spam
bacon spam tomato and spam;
End_of_Sketch;
$count = substr_count($sketch, "spam");
print("The word spam occurs $count times.");
The word spam occurs 14 times.
substr_replace( )函数允许使用不同方式对字符串进行修改:
$string = substr_replace(original, new, start [, length ]);
函数通过start (0的意思是字符串的开头)和 length指定的值,用字符串new替换original 的一部分。如果没有给出第四个参数,substr_replace( )删除从start 到字符串末尾的文字。
例如:
$greeting = "good morning citizen";
$farewell = substr_replace($greeting, "bye", 5, 7);
// $farewell 为 "good bye citizen"
设定length 为0来实现无删除的插入:
$farewell = substr_replace($farewell, "kind ", 9, 0);
// $farewell 为 "good bye kind citizen"
设定new 为 "" 来实现无插入的删除:
$farewell = substr_replace($farewell, "", 8);
// $farewell为 "good bye"
下面是说明如何在字符串的开头插入内容:
$farewell = substr_replace($farewell, "now it's time to say ", 0, 0);
// $farewell为 "now it's time to say good bye"'
如果Start 为负值,则指定从字符串末尾开始到字符串开头替换的字符数:
$farewell = substr_replace($farewell, "riddance", -3);
// $farewell为 "now it's time to say good riddance"
如果length为负值,则指定从字符串末尾开始删除的字符个数:
$farewell = substr_replace($farewell, "", -8, -5);
//$farewell 为 "now it's time to say good dance"
4.7.2 各种字符串函数
Miscellaneous String Functions
strrev()函数接收一个字符串然后返回一个翻转顺序的拷贝:
$string = strrev(string);
例如:
echo strrev("There is no cabal");
labac on si erehT
str_repeat( )函数接收一个字符串和一个计数参数,然后返回一个由参数string重复count次组成的新字符串:
$repeated = str_repeat(string, count);
例如,创建一个分隔线:
echo str_repeat('-', 40);
str_pad( )函数用另一个字符串填充一个字符串。可以选择用什么样的字符串来填充,以及加在左边、右边或两边都加:
$padded = str_pad(to_pad, length [, with [, pad_type ]]);
默认是以空格加在字符串右边:
$string = str_pad('Fred Flintstone', 30);
echo "$string:35:Wilma";
Fred Flintstone :35:Wilma
可选的第三个参数是要增加的字符串:
$string = str_pad('Fred Flintstone', 30, '. ');
echo "{$string}35";
Fred Flintstone. . . . . . . .35
可选的第四个参数可以是STR_PAD_RIGHT (默认)、 STR_PAD_LEFT或 STR_PAD_ BOTH(左右都加,长度均分,使原字符串居中对齐)。例如:
echo '[' . str_pad('Fred Flintstone', 30, ' ', STR_PAD_LEFT) . "]\n";
echo '[' . str_pad('Fred Flintstone', 30, ' ', STR_PAD_BOTH) . "]\n";
[ Fred Flintstone]
[ Fred Flintstone ]
4.7.3 分解字符串
Decomposing a String
PHP提供几个函数来将字符串分解为更小的部分。按复杂性递增排序,它们是explode( )、 strtok( )和sscanf( )。
4.7.3.1 分解和合并
数据常常以字符串的形式出现,同时必须要分解成一组值。例如,你可能想要在字符串中拆分以逗号分隔的字段,例如"Fred,25,Wilma"。在这些情况下,可以使用explode( )函数:
$array = explode(separator, string [, limit]);
第一个参数separator 是包含字段分隔符的字符串。第二个参数string 是要拆分的字符串。可选的第三个参数limit 是要返回数组中值的最大数目。如果达到上限的话,数组的最后一个元素会包含字符串剩余的部分:
$input = 'Fred,25,Wilma';
$fields = explode(',', $input);
// $fields 为 array('Fred', '25', 'Wilma')
$fields = explode(',', $input, 2);
// $fields为 array('Fred', '25,Wilma')
implode( )函数正好和explode( )相反——它用含有几个较小字符串的数组创建一个大字符串:
$string = implode(separator, array);
第一个参数separator是要放在第二个参数array元素间的字符串。要重建这个以逗号分隔的字符串,只需要这样做:
$fields = array('Fred', '25', 'Wilma');
$string = implode(',', $fields); // $string 是 'Fred,25,Wilma'
join( )函数是implode( )的别名函数。
4.7.3.2 Tokenizing 标记
strtok( )函数可用于遍历一个字符串,每次得到一个新的字符串块(标记,token)。第一次调用strtok( )的时候,需要传递两个参数:要遍历的字符串和标记分隔符:
$first_chunk = strtok(string, separator);
要得到剩下的标记,重复调用仅带有分隔符的strtok( ):
$next_chunk = strtok(separator);
例如,可以这样调用:
$string = "Fred,Flintstone,35,Wilma";
$token = strtok($string, ",");
while ($token !== false) {
echo("$token<br>");
$token = strtok(",");
}
Fred
Flintstone
35
Wilma
当没有任何标记可以返回时,strtok( )函数返回false。
如果再次调用strtok( )时带有两个参数,就会重新初始化迭代器。这样就可以从字符串的开头重新开始获取子字符串。
4.7.3.3 sscanf( )
sscanf( )函数依照和printf( )相似的模板来分解一个字符串:
$array = sscanf(string, template);
$count = sscanf(string, template, var1, ... );
如果没有使用可选变量的话,sscanf( )返回一个字段数组:
$string = "Fred\tFlintstone (35)";
$a = sscanf($string, "%s\t%s (%d)");
print_r($a);Array
(
[0] => Fred
[1] => Flintstone
[2] => 35
)
传递引用给变量,可以将字段存放在这些变量中,将返回字段的个数:
$string = "Fred\tFlintstone (35)";
$n = sscanf($string, "%s\t%s (%d)", &$first, &$last, &$age);
echo "Matched $n fields: $first $last is $age years old";
Matched 3 fields: Fred Flintstone is 35 years old
4.7.4 字符串查找函数
String-Searching Functions
有一些函数用于在一个较大字符串中查找字符串或字符。它们分为3个系列:strpos( )和strrpos( )返回1个位置,strstr( )、strchr( )等返回找到的字符串, strspn( )和strcspn( )返回字符串的开头有多少与掩码匹配。
字符的ASCII顺序值来查找。因此,下面的函数调用是相等的(因为44是逗号的ASCII值):
$pos = strpos($large, ","); //查找第一个逗号
$pos = strpos($large, 44); //也查找第一个逗号
如果没有找到指定的子串,所有的字符串查找函数都会返回false。如果子串出现在字符串的开头,函数就返回0。因为false可以转换为数字0,所以在测试失败时使用= = =来比较返回值:
if ($pos === false) {
//没有找到子串
} else {
//找到子串,$pos是字符串的偏移量。
}
4.7.4.1 返回位置的查找
strpos( )函数查找一个小字符串在较大字符串中第一次出现的位置:
$position = strpos(large_string, small_string);
如果没有找到小字符串,strpos( )返回false。
strrpos( )函数查找某个字符(注意是单个字符而不是字符串)在字符串中最后一次出现的位置。它的参数及返回值类型和strpos( )相同。
例如:
$record = "Fred,Flintstone,35,Wilma";
$pos = strrpos($record, ","); //查找最后一个逗号
echo("The last comma in the record is at position $pos");
The last comma in the record is at position 18
如果将一个字符串作为第二个参数传递给strrpos( ),只查找参数字符串的首字符。
那么如何查找一个字符串的最后出现位置呢? 请看下面的例子,先将字符串进行翻转并使用strpos( ):
$long = "Today is the day we go on holiday to Florida";
$to_find = "day";
$pos = strpos(strrev ($long), strrev($to_find));
if ($pos === false) {
echo("Not found");
} else {
//$pos是在反转字符串的中的位置
//转换为正常的字符串中的位置
$pos = strlen($long) - $pos - strlen($to_find);;
echo("Last occurrence starts at position $pos"); }
Last occurrence starts at position 30
4.7.4.2 返回剩余字符串的查找
strstr( )函数查找一个小字符串在大字符串中第一次出现的位置,并返回从小字符串开始的部分。例如:
$record = "Fred,Flintstone,35,Wilma";
$rest = strstr($record, ","); // $rest 为 ",Flintstone,35,Wilma"
strstr( )的变种有:
stristr( )
不区分大小写的strstr( )
strchr( )
strstr( )的别名
strrchr( )
查找字符在字符串中最后出现的位置
和strrpos( )一样,strrchr( )向后查找字符串,但是都只对字符,而不是一整个字符串。
4.7.4.3 使用掩码查找
如果认为strrchr( )深奥,那么你还没有真正理解它。strspn( )和strcspn( )函数告诉你字符串开头有多少个指定的字符:
$length = strspn(string, charset);
例如,下面的函数测试一个字符串是否包含一个八进制数字:
function is_octal ($str) {
return strspn($str, '01234567') == strlen($str);
}
strcspn( )里的c代表complement(补足物),它说明字符串的开头有多少不是由字符集中的字符组成。当感兴趣的字符比不感兴趣的字符多时,使用strcspn()函数。例如,下面的函数测试一个字符串中是否有任何空字符、制表符或回车:
function has_bad_chars ($str) {
return strcspn($str, "\n\t\0") == strlen($str);
}
4.7.4.4 分解URL
parse_url( )函数返回一个由URL成分组成的数组:
$array = parse_url(url);
例如:
$bits = parse_url('http://me:secret@example.com/cgi-bin/board?user=fred);
print_r($bits);
Array
(
[scheme] => http
[host] => example.com
[user] => me
[pass] => secret
[path] => /cgi-bin/board
[query] => user=fred
)
得到的数组键名可能为scheme、host、port、user、pass、path、query和 fragment。







