030-字符串系统函数讲解
<?php
/*
字符串函数讲解
PHP中,字符串函数非常非常多,
在此,归为9类,
每类,有代表的讲解1-2个.
严重警告同学们:
务必把老师PPT上列出的字符串函数练习遍.
同时,也学会看手册.
*/
$str = 'hello';
echo 'hello有',strlen($str),'个字节';
echo '<br />';
$str2 = '中国';
echo '中国有',strlen($str2),'个字节';
/**
为什么"中国"是6个字节呢?
我们的.php文件,是utf-8编码.
中文在utf-8编码规则中,一个中文,占3个字节.
因此,'中国'占6个字节.
**/
?>
<?php
$str = 'hello';
echo 'hello有',strlen($str),'个字节';
echo '<br />';
$str2 = '中国';
echo '中国有',strlen($str2),'个字节';
// 而英文字符,是Ascii字符,几乎在所有的硬件/软件下,Ascii都是兼容的,都是1个字符.
?>
<?php
$str = "中华民国";
echo '字节长度是',strlen($str),'<br />'; // 12
echo '字符长度是',mb_strlen($str,'utf-8'),'<br />';
/**
要知道,编码都是有规律的,
utf-8有utf-8的规律,
你告诉mb_strlen,用utf8的规则来判断字符串,
判断出是4个字符.
**/
/*
strlen 是计算字符串"字节"长度
mb_strlen,是根据编码,计算字符串的"字符"个数.
*/
?>
<?php
// 查找字符串中子字符串的位置
$str = 'how are you! fine thank you,fine, may be you are right, 256, I dont think so,let
me see,I can not fine';
// 经理说: 你能否找找,这段字符串里,有没有'fine'
echo strpos($str,'fine'),'<br />'; // 13,经过13字节后,找到了fine
var_dump(strpos($str,256)); // 没找到,false
var_dump(strpos($str,97)); // 97找到了,返回值是4
/**
在计算机里,ascii字符集中
65 -> 90 , A-Z
97 -> 122 , a-z
当你第2个参数,写的是整型时,则把理解为是ascii字符的编码
所以 int 97 === 'a';
不熟悉ascii的,百度"ascii 码表"
**/
// 第3个参数offset的讨论
echo strpos($str,'fine'),'<br />'; // 13,经过13字节后,找到了fine
// 经理又说话了, 这个fine,还有没有fine???
// 第3个可选参数,offset的作用,就体现出来了.
// offset 的意思是 ---偏移量.
// 就是说,把光标先偏移一段距离,再查找,别从头查找.
echo strpos($str,'fine',17),'<br />';
?>
<?php
// 1:写一个函数,判断指定的父串中,有没某子串
function findsub($str,$find) {
if(strpos($str,$find)){
return true;
} else {
return false;
}
}
function findsub2($str,$find) {
if(strpos($str,$find) === false){
return false;
} else {
return true;
}
}
$title = 'today is sunny';
if(findsub($title,'is')) {
echo '有is子串<br />';
} else {
echo '没有is子串<br />';
}
/*
下面这个判断,出问题了,
因为strpos返回了0, 而0用if判断时,当成false来处理的.
*/
if(findsub($title,'today')) {
echo '有today子串<br />';
} else {
echo '没有today子串<br />';
}
if(findsub2($title,'today')) {
echo '有today子串<br />';
} else {
echo '没有today子串<br />';
}
?>
<?php
// 用for循环或者while循环, 配置strpos
// 计算某父串中, 子串出现的个数?
/*
函数名 subnum
参数: string $str 待查父串,
string $sub,子串
return int ,即子串个数
*/
/*
思路:
先从头查找子串,找到后,则偏移过去子串,继续查找. 直到查不到.
*/
function subnum($str,$sub) {
$sublen = strlen($sub); // 计算出子串的长度
$strlen = strlen($str); // 计算出父串的长度
if($sublen > $strlen) {
return 0;
} // 如果子串比父串长,没必要找了
for($offset = 0,$num=0;($offset = strpos($str,$sub,$offset))!==false;) {
$num += 1;
$offset += $sublen;
}
/* 如果你熟悉for循环,可以这么写
for($offset = 0,$num=0;($offset = strpos($str,$sub,$offset))!==false;$num += 1,$offset
+= $sublen) {
}
*/
return $num;
}
$str = 'how are you! fine thank you,fine, may be you are right, 256, I dont think so,let
me see,I can not fine';
echo '找到',subnum($str,'fine'),'个fine';
echo '<br />';
/*
知识综合起来,就能发挥比较大的作用,
此处用的for循环 + strpos, 计算子串的个数
*/
echo '我也找到',substr_count($str,'fine'),'个fine';
/*
这是为什么让大家重视字符串,
PHP的字符串太强大了.
你要是不了解,可能会多花冤枉时间,费力写出一个函数来,结果,本来就有.
*/
?>
031-字符串系统函数(2)
<?php
/*
str_replace 字符串替换函数
str:string 字符串
replace: 替换
*/
// 准备,把hi换成hello
$str = 'hi,this is lily,history';
$newstr = str_replace('hi','hello',$str);
echo $str,'<br />',$newstr,'<br />';
// 能不能帮我统计一下,替换了几次呢?
$newstr = str_replace('hi','hello',$str,$num);
echo $str,'<br />',$newstr,'<br />';
echo '替换hi',$num,'次';
echo '<hr />';
// 再次要求,把hi换成hello, 再把li 换成 ul
// 可以用数组参数,指定多种替换.
$search = array('hi','li');
$replace = array('hello','ul');
$newstr = str_replace($search,$replace,$str);
echo $newstr,'<br />';
/*
hi 单词===>hello单词
但
this单词中间的一部分的hi,也被换了,导致this单词都错了.
能不能,专替换hi单词呢?
如果hi是单词的一部分,则不替换?
*/
/*
突然奇想,
hi=>hello, hello=>hi
*/
$str = 'hi lily, hello jim';
$newstr = str_replace(array('hi','hello'),array('hello','hi'),$str);
echo $newstr,'<br />'; // 觉得应该变成 hello lily, hi jim, 实际打印是 hi lily,hi jim
/**
分析:
hi->hello
hello lily, hello jim
hello->hi
hi lily, hi jim
**/
/*
strtr ,以单个字符对应来替换的
比如 strtr($str,'hi','ab'), 则执行 h->a ,i->b
如果看着不舒服,可以换个写法
*/
$str = 'hi lily, hello jim';
echo strtr($str,'hi','ab'),'<br />';// he lely, hello jem
// 用户在网站有可能输入全角字符,由我们的程序统一把全角转半角
$str = '你好。,12345,';
echo strtr($str,array('1'=>'1','2'=>'2'));
/****
全半角转换,用strtr非常方便
在网站开发中,这个功能也常见.
比如,ecshop里就有,如下
function make_semiangle($str)
{
$arr = array('0' => '0', '1' => '1', '2' => '2', '3' => '3', '4' => '4',
'5' => '5', '6' => '6', '7' => '7', '8' => '8', '9' => '9',
'A' => 'A', 'B' => 'B', 'C' => 'C', 'D' => 'D', 'E' => 'E',
'F' => 'F', 'G' => 'G', 'H' => 'H', 'I' => 'I', 'J' => 'J',
'K' => 'K', 'L' => 'L', 'M' => 'M', 'N' => 'N', 'O' => 'O',
'P' => 'P', 'Q' => 'Q', 'R' => 'R', 'S' => 'S', 'T' => 'T',
'U' => 'U', 'V' => 'V', 'W' => 'W', 'X' => 'X', 'Y' => 'Y',
'Z' => 'Z', 'a' => 'a', 'b' => 'b', 'c' => 'c', 'd' => 'd',
'e' => 'e', 'f' => 'f', 'g' => 'g', 'h' => 'h', 'i' => 'i',
'j' => 'j', 'k' => 'k', 'l' => 'l', 'm' => 'm', 'n' => 'n',
'o' => 'o', 'p' => 'p', 'q' => 'q', 'r' => 'r', 's' => 's',
't' => 't', 'u' => 'u', 'v' => 'v', 'w' => 'w', 'x' => 'x',
'y' => 'y', 'z' => 'z',
'(' => '(', ')' => ')', '〔' => '[', '〕' => ']', '【' => '[',
'】' => ']', '〖' => '[', '〗' => ']', '“' => '[', '”' => ']',
'‘' => '[', '’' => ']', '{' => '{', '}' => '}', '《' => '<',
'》' => '>',
'%' => '%', '+' => '+', '—' => '-', '-' => '-', '~' => '-',
':' => ':', '。' => '.', '、' => ',', ',' => '.', '、' => '.',
';' => ',', '?' => '?', '!' => '!', '…' => '-', '‖' => '|',
'”' => '"', '’' => '`', '‘' => '`', '|' => '|', '〃' => '"',
' ' => ' ');
return strtr($str, $arr);
}
****/
?>
032-字符串函数详解(3)
<?php
// 截取子字符串
// substr
/*
string substr ( string $string , int $start [, int $length ] )
$string: 待截取的长字符串
start: 截取开始的位置
$length: 正数时代表截取的长度,负数时代表截取结束的位置
*/
$str = 'abcdefg';
/*
当第3个参数,不指定时,截取到字符串的"结尾"
*/
echo substr($str,3),'<br />'; // defg
/*
经理说:把字符串末尾的3个字符截取出来
又怎么办呢?
*/
// 办法1,先算出length,再-3
$str = 'abcdefg';
$start = strlen($str) - 3;
echo substr($str,$start),'<br />';
// 办法2,起始位置不走左数,而是呢,填负数,从右往左数.
echo substr($str,-3),'<br />';
/**
经理又要求:
专门截取字符串开头的3个字符
分析:start 应该填0
截取长度: length 应该填3
**/
// 第3个参数为正数时,代表要截取的长度
$str = 'abcdefghijk';
echo substr($str,0,3),'<br />';
/**
经理又要求:
专门截取除了头3位,和尾巴3位,
即,中间的那些字符串.
分析:start应该是3
length,如何代表长度,多长呢? 不一定,因为字符串的长度不好算.
这时,可以把length写成负数.
如果length是负数,不代表长度,代表
**/
$str = '123456789';
echo substr($str,3,-3),'<br />';
// 至此,经理没能刁难你,完成任务
/**
这时,我们对经理说:"还需要截什么吗? 中文我也能截,来点任务吧"
substr 它是按字节来操作的,不考虑什么编码.
**/
$str = '中华民国'; // 我的文件是utf-8编码的.
echo substr($str,6,3),'<br />';
/*
经理说:"小样儿,牛叉是吗"
来截这一段"lily你的代码report给我,中午我们有个meeting,一会带你吃KFC"
*/
$str = "lily你的代码report给我,中午我们有个meeting,一会带你吃KFC";
echo substr($str,0,6),'ab';
// 按字节截,'lily你'是7个字节才完成
// '你'的3个字节,被截了2个,出了问题.
/**
面试题:如何截取中文无乱码,假设UTF-8编码
1: 用系统函数,自己找
2: 根据utf8的编码规则,用substr自己截.
后面:有字符编码专题,同学们可以先研究一下.
**/
?>
<?php
/*
strstr($str,$needle)
作用: 是在$str中找到指定的$needle,而且是$needle第一次出现的位置,
返回该位置直到字符串结尾的这一部分
*/
$str = 'abc.def.jpg.exe';
echo strstr($str,'.'),'<br />'; // .def.jpg.exe
/***
经理说:
能否把第一次找到的$needle的位置 之前的字符串截出来呢?
答:能,从PHP5.3.0版本开始,strstr函数多了第3个可选参数,
***/
echo strstr($str,'.',true),'<br />';
// strstr === strchr 函数,
/**
经理说,
能否先把$needle 最后一次出现的位置找出来,
从该位置,一直截到结尾.
答:strchr
**/
echo strrchr($str,'.'),'<br />';
/// 面试时,让你计算一个文件的后缀?
$file = 'new.txt';
echo strrchr($file,'.');
?>
<?php
// 字符串 分割,反转,拼接
$str = 'abcdef';
$arr = str_split($str);
// 发现,把字符串的字符,拆成了数组,每个单元一个字符.
print_r($arr);
// 经理问: 能不能2个字符一个单元, 拆成数组.
$arr = str_split($str,2);
print_r($arr);
// 截取到最后,如果剩下的字符串,不够长度N,那就剩下当一组.
$arr = str_split($str,4);
var_dump($arr);
?>
<?php
// PHP中,字符串函数和数组函数最多,
// 字符串和数组,有2个函数,是他们的桥梁,非常频繁的使用.
// 就是implode,和explode
// 有的网站,写文章时,让我们填写标签,"多个标签用逗号隔开"
$str = 'abc,中国,美国,日本';
// explode,是根据指定的分割符,把字符串拆成数组.
$arr = explode(',',$str);
print_r($arr);
// implode,是根据指定的连接符,把数组再拼接成字符串
$arr = explode(',',$str);
echo implode('~',$arr),'<br />';
// 你可以只传一个数组做参数,不指定连接符,
// 这样,将把数组单元直接拼接起来
echo implode($arr);
?>
<?php
$str = '12345678';
echo chunk_split($str,3,','); // 每隔3个长度,加一个','
// 不说明第3个参数,则加换行符.
// 想: 把12345678 转换成 12,345,678 的格式.
?>
<?php
// 字符转义函数,非常重要
$str = "abc ', hello";
echo $str,'<br />';
/***
现在我们还没有学习mysql,你可以还意识不到一个单引号的破坏作用.
但要知道,单双引号如果不小心,数据库是会被注入的.
应该把客户输入进来的数据,进行转义,防止单双引号带来的破坏.
***/
echo $str2 = addslashes($str),'<br />'; // 单引号被转义成 \'
// 能不能把\',转回 '
// 答:能
echo stripslashes($str2),'<br />';
$str = '<ab>';
echo $str;
echo htmlspecialchars($str);
/**
htmlspecialchars --> 特殊符号转成html实体
htmlspecialchars_decode--> 实体转成符号
**/
?>
<?php
if(strcmp('D','a') > 0) {
echo 'D>a';
} else if(strcmp('D','a') < 0) {
echo 'D < a';
} else {
echo '相等';
}
// D比a还小, 因为是按二进制中 ascii码比的.
?>
<?php
// 大小写转换
$str = 'HeLLo, ThiS IS LilY, BUT,I LoVE HanMEImei';
// 转成小写
echo strtolower($str),'<br />';
// 转成大写
echo strtoupper($str),'<br />';
// 每个单词的首字母大写
// 但是,只是帮你把每个单词的首字母变大写,其他的字母,他不做影响.
echo ucfirst($str),'<br />';
// 因此,我们想把每个单词的首字母大写,而且,只有首字母大写.
echo ucfirst(strtolower($str));
?>
033-字符串面试题讲解
<?php
$str = 'abcdef';
// 打印出字符串的第1个字母
echo substr($str,0,1),'<br />';
// 字符串还有类数组的特性, 即可以用索引/下标,把指定的字符取出来
echo $str[0],'<br />';
// 如何实现字符串反转
$str = 'abcde';
function rev($str) {
$len = -strlen($str);
for($new = '',$start=-1; $start >= $len; $start--) {
$new .= substr($str,$start,1);
}
return $new;
}
echo rev($str),'<br />';
echo strrev($str); // 系统自带的字符串反转函数.
?>
<?php
// 用5种以上方式获取文件的后缀
// 例: a.jpeg.exe, 获得 exe,或者 .exe
$file = 'a.jpeg.exe';
// 方法1
function getext($file) {
return strrchr($file,'.');
}
echo getext($file),'<br />';
// 找最后一个 . 出现的位置,再substr截取
// strrpos是找子字符最后一次出现的位置
//
$file = 'a.jpeg';
function getext2($file) {
return substr($file,strrpos($file,'.'));
}
echo getext2($file),'<br />';
// 把字符串反过来,然后再找第一个点出现的位置.
function getext3($file) {
$file = strrev($file);
return strrev(substr($file,0,strpos($file,'.')));
}
echo getext3($file),'<br />';
// 用系统函数 pathinfo
function getext4($file) {
/*
$arr = pathinfo($file);
return $arr['extension'];
*/
return pathinfo($file,PATHINFO_EXTENSION);
}
echo getext4($file);
// 如果学了数组,还可以有多种做法. 先讨论到此.
?>
<?php
// 把1234567,转成 1,234,567的形式
$num = '1234567';
function t1($num) {
$arr = str_split(strrev($num),3);
return strrev(implode(',',$arr));
}
print_r(t1($num));
echo '<br />';
function t2($num) {
$num = strrev($num);
$num = strrev(chunk_split($num,3,','));
$num = ltrim($num,',');
return $num;
}
print_r(t2($num));
echo '<br />';
// 系统函数,一句话搞定.
echo number_format($num);
?>