代码改变世界

第四章 字符串操作与正则表达式(4)

2016-07-28 20:18  yojiaku  阅读(512)  评论(0编辑  收藏  举报

4.4 字符串的比较

目前,我们已经使用了"=="来比较两个字符串是否相等。PHP可以进行一些更复杂的比较,我们分为两类:部分匹配和其他情况。首先讨论其他情况,然后再讨论在进一步开发Smart例子(智能表单邮件)中要用到的部分匹配。

1.字符串排序:strcmp(), strcasecmp(), strnatcmp()

  strcmp():int strcmp(string str1, string str2);

          其中str1和str2是需要进行比较的两个字符串。如果str1 和 str2 相等,strcmp()函数就返回0,如果按字典顺序str1在str2后面(即str1>str2)就返回一个正数,如果str1<str2就返回一个负数。

          区分大小写。

          举例:

#strcmp()
$var1 = "Hello";
$var2 = "hello";
if (strcmp($var1, $var2) !== 0) {
    echo '$var1 is not equal to $var2 in a case sensitive string comparison';
}else{
    echo '$var1 is equal to $var2 in a case sensitive string comparison';
}

          注意:这里echo结构中使用的是单引号(''),这样就可以在输出结果是保持$var1和$var2,而不是出现两个变量所表示的值。这个例子主要在用strcmp()函数比较var1和var2是否相等,如果相等,就打印else中的语句,反之,打印if中statement1的语句。

          输出结果:

          在php手册关于strcmp()函数的讲解中有个小小的tip:If you rely on strcmp for safe string comparisons, both parameters must be strings, the result is otherwise extremely unpredictable.(即如果你想以来strcmp函数来比较两个字符串,必须确保它的两个参数都是字符串,否则无法预料返回值的情况。)

For instance you may get an unexpected 0, or return values of NULL, -2, 2, 3 and -3.

strcmp("5", 5) => 0
strcmp("15", 0xf) => 0
strcmp(61529519452809720693702583126814, 61529519452809720000000000000000) => 0
strcmp(NULL, false) => 0
strcmp(NULL, "") => 0
strcmp(NULL, 0) => -1
strcmp(false, -1) => -2
strcmp("15", NULL) => 2
strcmp(NULL, "foo") => -3
strcmp("foo", NULL) => 3
strcmp("foo", false) => 3
strcmp("foo", 0) => 1
strcmp("foo", 5) => 1
strcmp("foo", array()) => NULL + PHP Warning
strcmp("foo", new stdClass) => NULL + PHP Warning

strcmp(function(){}, "") => NULL + PHP Warning

          与strcmp()函数类似的还有similar_text()函数:Calculate the similarity between two strings(即计算两个字符串的相似度:int similar_text(string $str1, string $str2 [, float &$percent]);)--percent表示str1和str2的相似度,举例:

$var_1 = 'PHP IS GREAT'; 
$var_2 = 'WITH MYSQL'; 

similar_text($var_1, $var_2, $percent); 

echo $percent; 
// 27.272727272727 

similar_text($var_2, $var_1, $percent); 

echo $percent; 
// 18.181818181818 

        注意:在similar_text()函数中,str1和str2的位置很重要(在例子中已经清晰地展现出来了),这个例子的意思是'PHP IS GREAT'与'WITH MYSQL'的相似程度为27.272727272727,而'WITH MYSQL'与'PHP IS GREAT'的相似程度为18.181818181818.在php手册的similar_text()中也有一个小小的tip:(即如果比较两个空字符串,则两者相似程度为0)。

Please note that this function calculates a similarity of 0 (zero) for two empty strings.

<?php
similar_text("", "", $sim);
echo $sim; // "0"
?>

  strcasecmp():int strcasecmp(string str1, string str2);该函数的作用痛strcmp()函数一样,只是不用区分大小写,即

#strcasecmp()
$var1 = "Hello";
$var2 = "hello";
if (strcasecmp($var1, $var2) !== 0) {
    echo '$var1 is not equal to $var2 in a case sensitive string comparison';
}else{
    echo '$var1 is equal to $var2 in a case sensitive string comparison';
}

        它的输出结果是:$var1 is equal to $var2 in a case sensitive string comparison .

  strnatcmp():int strnatcmp( string $str1, string $str2); 返回值与strcmp()函数一致。举例说明strnatcmp()函数与strcmp()函数的不同:

<?php
$arr1 = $arr2 = array("img12.png", "img10.png", "img2.png", "img1.png");
echo "Standard string comparison\n";
usort($arr1, "strcmp");
print_r($arr1);
echo "\nNatural order string comparison\n";
usort($arr2, "strnatcmp");
print_r($arr2);
?>

       它的输出结果是:

Standard string comparison
Array
(
    [0] => img1.png
    [1] => img10.png
    [2] => img12.png
    [3] => img2.png
)

Natural order string comparison
Array
(
    [0] => img1.png
    [1] => img2.png
    [2] => img10.png
    [3] => img12.png
)
      我们可以看到,strcmp函数是先把以“1”开头的字符串大小进行比较,比较完了再进行以“2”开头的比较(自然顺序);而strnatcmp函数的比较是按照大小顺序进行。

strnatcasecmp():用法与strnatcmp()一样,不同在于它不用区分大小写,且与strcmp一样按照自然顺序进行比较。

2.使用strlen()函数测试字符串的长度
strlen(): int strlen(string str);返回输入字符串的长度,我们通常使用这个函数来验证输入的数据,例如,我们考虑一个电子邮件地址,根据推理,如果一个国家的代码没有二级域名(.com.net),
只有一个字母的服务器名称和一个字母的电子邮件地址,那么它的最小长度是6个字符--a@a.to。因此,如果一个地址没有达到这个长度就会报错:
#strlen()
$email = 'a@a.n';
if(strlen($email) < 6){
    echo 'That email address is not valid';
    exit; //force execution of PHP script
}

输出结果是:That email address is not valid .

4.5 使用字符串函数匹配和替换子字符串

例子:通过Bob客户的反馈信息中的一些关键词来将它们发送给不同部门的人。即如果希望将Bob商店的心间发到销售经理那,就需要知道消息中是否出现shop或它的派生词(shopping,shopped)。——检查一个字符串中是否包含特定的子字符串。

方法一:使用函数explode()和strtok()在消息中检索每个单词,然后通过“==”或函数strcmp()对它们进行比较。

方法二:调用一个字符串函数或正则表达式匹配函数。(这些函数可以用于在一个字符串中搜索一个模式)

4.5.1 在字符串中查找字符串:strstr(), strchr(), strrchr(), stristr()

  strstr():string strstr(string $haystack, mixed $needle[, bool $before_needle = false]);

      haystack:The input string (输入的字符串即要长字符串)

      needle:如果needle不是一个字符串,它就会被转换为一个整数和应用作为字符的顺序的值。(needle是需要查找的子字符串,即目标关键字字符串参数)

      返回值:如果找到了目标关键字的一个精确匹配,函数就会从目标关键字前面返回被搜索的字符串,否则返回值为false;如果存在不止一个目标关键字,返回的字符串从出现第一个目标关键字的位置开始。

$toaddress = "xxxx@qq.com";
//Change the $toaddress if the criteria are met
if(strstr($feedback, 'shop'))
    $toaddress = 'retail@example.com';
else if(strstr($feedback, 'delivery'))
    $toaddress = 'fulfillment@example.com';
else if(strstr($feedback, 'bill')){
    $toaddress = 'account@example.com';
}

解释:首先,这段代码将检查反馈信息中的关键字,然后将邮件发送给不同的人。例如:如果客户的反馈信息是“I still have not received delivery of my last order.”,中出现了“delivery”,那么就会发送给fulfillment@example.com。

函数strstr()有两个变体,一个是stristr(),其作用与strstr()一样,只是不区分大小写。 第二个是strrchr(),用途也一样,只是会从最后出现目标关键字的位置的前面返回被搜索字符串。

#strstr()
$array = "name@example.com";
$array1 = strstr($array, '@');
echo $array1;
echo "<br />";
$array2 = strstr($array, '@',true);
echo $array2;

输出结果:@example.com
     name

当我们使用第三个参数时,函数返回的是needle前的被搜索字符串;当我们不使用第三个参数时,函数返回的是needle后的被搜索字符串。

4.5.2 查找子字符串的位置:strpos(), strrpos()

这两个函数用法跟strstr()差不多,只不过他们返回的是目标关键字子字符串在被搜索字符串中的位置:

#strpos()
$array = "name@example.com";
$array3 = strpos($array, '@');
echo $array3."<br />";

输出结果为:4,即@出现在name@example.com的第四位(从0开始计算)

strpos()返回的是第一次出现的位置,而strrpos()返回的是最后一次出现的位置。

有一个小小的tip:如果目标关键字不在字符串中,将返回false,而false在php中相当于0,我们用下面的方法来区别:

$result = strpos($test, "H");

if($result === false){

  echo "Not found";

}else{

  echo "Found at position".$result;

}

4.5.3 替换子字符串:str_replace(), substr_replace()