目录
- 基本语法
- 语句结构
- 函数
- 数组
- 面向对象的程序设计
- 字符串
- 正则表达式
- 常用函数
- 文件系统
- 图形图像处理
- MySQL数据库
- Cookie&Session
- 错误和异常
正则表达式
正则表达式语法
- 是一种描述字符排列模式的一种自定义语法规则。
- 在PHP中可以使用函数联合正则表达式对字符串进行匹配,查找,分割,替换等操作。
- 正则表达式由原子(普通字符,例如字母A~Z),元字符(有特殊功能的字符,例如*,+和?等)及模式修正符3部分组成。
- 一个简单的正则表达式,至少要包含一个原子。
在使用PCRE库函数是,一定要给正则表达式加上定界符。
定界符和原子
定界符
- 使用PCRE正则表达式通常把函数放入定界符之间。
- 定界符不局限于反斜杠“\”。除了字母数字和正斜杠“/”之外的全部字符都可以作为定界符。
原子
- 原子是正则表达式最基本的单位,而且每个模式至少包含一个原子。
- 原子是由所有那些未指定为元字符的打印和非打印字符组成。
原子字符 | 描述 |
---|---|
\cx | 匹配由x指明的控制字符。\cM匹配一个Control-M或回车符。x的值必须为A~Z或a~z之一,否则,将c视为一个原义的’C’字符 |
\f | 匹配一个换页符 |
\n | 匹配一个换行符 |
\r | 匹配一个回车符 |
\t | 匹配一个制表符 |
\v | 匹配一个垂直制表符 |
元字符
- 用于构建正则表达式的具有特殊含义的字符。
- 如果要在正则表达式中包含元字符本身,则必须在其前面加上“\”进行转义。
字符 | 描述 |
---|---|
$ | 匹配输入字符串的结尾位置。如果设置了RegExp对象的Multiline属性,则$也匹配‘\n’或‘\r’ |
() | 标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用 |
* | 匹配前面的子表达式零次或多次 |
+ | 匹配前面的子表达式一次或多次 |
. | 匹配除换行符\n之外的任何单字符 |
[] | 匹配方括号中指定的任意一个原子 |
[^] | 匹配除方括号内原子以外的任意字符 |
? | 匹配前面的子表达式零次或一次,或指明一个非贪婪限定符 |
\ | 将下一个字符标记为特殊字符,原义字符,向后引用,八进制转义符中的一种 |
^ | 匹配输入字符的开始位置,除非在方括号中使用表示不接受该字符集合 |
| | 指明两项之间的一个选择 |
\s | 匹配任何空白字符,包括空格,制表符,换页符等 |
\S | 匹配任何非空白字符 |
\w | 匹配任意一个数字,字母或下划线 |
\W | 匹配除数字,字母或下划线以外的任意字符 |
\b | 匹配单词的边界 |
\B | 匹配除单词边界以外的部分 |
{n} | 表示其前面的原子正好出现n次 |
{n,} | 表示其前面的原子至少出现n次 |
{n,m} | 表示其前面的原子至少出现n次,之多出现m次 |
通用字符类型
- 通用字符类型可以匹配相应类型中的任意一个字符。
- 使用原子表也可以实现同样的功能。例如“[0-9]”就和“\d”的功能是一样的。
正则表达式表示电子邮箱格式
marshall@gmail.com
//邮箱格式
<?php
/^[a-zA-Z0-9_]+@[a-zA-Z0-9_]+(\.[a-zA-Z0-9_]+){1,3}$/
//原子表形式
/^\w+@\w+(\.\w+){1,3}$/
//通用字符形式
?>
限定符
- 限定符共有6种:“*”,“+”,“?”,“{n}”,“{n,}”,“{n,m}”。
- 它们的区别在于匹配次数不同。
- “*”,“+”,“{n,}”都是贪婪限定符,会尽可能多的匹配字符。
<?php
/a\s*b/ //匹配在a和b之间没有,有一个或者多个空白的情况
/a\d+b/ //匹配在a和b之间有一个或者多个数字的情况
/a\\W?b/ //匹配在a和b之间没有或者有一个特殊字符的情况
/az{2}b/ //匹配在a和b之间必须有两个z的情况
/az{2,}b/ //匹配在a和b之间至少有两个z的情况
/az{2,5}b/ //匹配在a和b之间至少有2~5个z的情况
?>
边界限制
- 边界限制用来限制字符串或者单词的边界,以获得更精准的匹配结果。
- “^”和“$”分别表示字符串的开始和结束。
- “\b”用于匹配字符串中每个单词的前或后边界。“\B”表示非单词边界。
<?php
/^this/ //匹配this
/\bis\b/ //匹配is
/PHP$/ //匹配PHP
/\Bis\b/ //匹配没有左边界有右边界的is
/\bis\b/ //匹配有左右边界的is
?>
原点(.)
- 原点可以匹配目标中的任意一个字符,包括非打印字符。
- 在默认情况下,它不匹配换行符。
<?php
/a.b/
?>
模式选择符(|)
- ”|“用来分割多个选择,例如,”PHP|HTML“可以匹配”PHP“,也可以匹配”HTML“。
原子表[ ]
- 原子表”[]“可以匹配一组彼此平等的原子,且从原子表中仅选择一个原子进行匹配即可。
- 在原子表中可以使用符号”-“来连接ASCII码顺序排列的原子,能够简化书写
<?php
/[abcp]hp/ //匹配项 ahp bhp chp php
/[^abc]hp/ //匹配项 ehp fhp 3hp
/0[xX]0-9A-F/ //匹配项 0x3F 0X9A 0x5C
?>
模式单元
- 模式单元是使用元字符”()“将多个原子组成大的原子被当做一个原子使用。
- 模式单元中的表达式将被优先匹配
<?php
/(very)*good/ //匹配项 good verygood veryveryverygood
//"very"被当做一个整体来匹配,因此可以没有也可以有多个
?>
向后引用
- 由于模式单元是多个原子,因此这个模式单元会存储在一个临时缓冲区。
- 缓冲区的编号从1开始,最大可以到编号99.
- 可以使用”\x“来访问缓冲区的内容,”x“表示编号。在正则表达式中还需要在前面加一个\。
<?php
/\d{4}(\w)\d{2}\\1\d{2}/ //\1引用了\w
?>
- 在模式单元匹配成功后,缓存区中的内容就会更新。缓冲区更新就导致了引用的改变,也就是说在模式单元匹配后引用它的地方都要使用匹配的这个原子。
<?php
/\d{4}(\w)\d{2}\\1\d{2}/ //\1引用了\w
//2014*12*12
/\d{4}(\w)\d{2}\\1\d{2}/
//2014:12:12
?>
- 当然这种更新缓冲区是可以由我们控制的,使用”?:“来阻止模式单元被储存。
<?php
/(windows)(linux)\\2/ //引用第二个缓冲区的内容
/(?:windows)(linux)\\1/ //第一个模式单元被阻止储存
?>
模式匹配的优先级
- 相同优先级从左向右运算,不同优先级按优先级从高到低的顺序运算。
优先级 | 元字符 | 描述 |
---|---|---|
1 | |转义符 | |
2 | (),(?:),[] | 模式单元和原子表 |
3 | *,+,?,{n},{n,},{n,m} | 重复匹配 |
4 | ^,$,\b,\B | 边界限制 |
5 | | | 模式选择 |
模式修正符
- 模式修正符在正则表达式的定界符之外使用。
- 模式修正符也是可以组合使用的。
- 模式修正符对编写简洁的正则表达式有很大的帮助。
模式修正符 | 描述 |
---|---|
i | 不区分大小写的匹配 |
m | 将字符串视为多行,不管是哪行都能匹配 |
s | 将字符串视为单行,换行符作为普通字符 |
x | 将模式中的空白忽略 |
e | 配合函数preg_replace()使用,可以把匹配来的字符串当做正则表达式执行 |
A | 强制从目标字符串开头开始匹配 |
D | 如果使用了$限制字符串,则不允许结尾有换行 |
S | 如果设定了此修正符则会进行额外的分析 |
U | 只匹配最近的一个字符串,不重复匹配 |
正则表达式函数
PHP支持两套正则表达式处理函数库。
- ”preg_“为前缀名的PCRE库提供的函数。
- ”ereg_“为前缀名的POSIX库提供的函数。
函数名 | 描述 |
---|---|
preg_match() | 进行正则表达式匹配 |
preg_match_all() | 进行全局正则表达式匹配 |
preg_replace() | 进行正则表达式的搜索和替换 |
preg_split() | 用正则表达式分割字符串 |
preg_grep() | 返回与模式匹配的数组元素 |
preg_replace_callback() | 用回调函数执行正则表达式的搜索和替换 |
字符串查找与替换
- 字符串匹配与查找是字符串操作中非常重要的内容之一。对于一些比较复杂的字符串替换操作,可以通过正则表达式的替换函数完成。
preg_match()
- preg_match()用于执行一个正则表达式的匹配。
- 返回匹配的次数,0表示没有匹配项,1表示有匹配项。
preg_match($pattern,$subject,&$matches,$flags,$offset)
//函数名+接受搜索模式+接受字符串+可选参数(搜索结果组成的数组+使返回结果附加偏移量+指定开始搜索的字符串位置)
//如果设置了第4个参数$flage,则第3个参数$matchesの返回结果会受到影响
//$flage只可以被设置为“PREG_OFFSET_CAPTURE”
<?php
$email_a='marshall123@gmail.com';
$email_b='marshall123$gmail.com';
$res=preg_match('/^\w+@\w+(\.\w+){1,3}$/',$email_a);
if($res)
{
echo '你的邮箱是合法的';
}
else
{
echo '你的邮箱是不合法的';
}
$res=preg_match('/^\w+@\w+(\.\w+){1,3}$/',$email_b);
if($res)
{
echo '你的邮箱是合法的';
}
else
{
echo '你的邮箱是不合法的';
}
?>
使用preg_match()并传入多个参数来匹配网址中的域名
<?php
preg_match('#^(?:http://)?([^/]+)#i','http://www.google.com/index.html',$matches);
echo '数组的第一个元素内容是:'.$matches[0].'<br/>';
echo '数组的第二个元素内容是:'.$matches[1].'<br/>';
$host=$matches[1];
preg_match('/[^.]+\.[^.]+$/',$host,$matches);
?>
//返回的数组第一个元素将包含完整模式匹配到的文本,第二个元素将包含第一个捕获子组匹配到的文本
<?php
$str='This is PHP!';
preg_match('/(\w+) is/i',$str,$res);
print_r($res);
?>
<?php
$str='This is PHP!';
preg_match('/\bis\b/i',$str,$res,PREG_OFFSET_CAPTURE); //结果相对原字符串的偏移量
print_r($res);
?>
<?php
$str='This is PHP!';
preg_match('/d/',$str,$res,PREG_OFFSET_CAPTURE,4); //从第4个字符串开始搜索
print_r($res);
?>
preg_match_all()
- preg_match_all()会一直搜索到字符串的结尾,获取所有的匹配项。
preg_match_all($pattern,$subject,&$matches,$flags,$offset)
//函数名+接受搜索模式+接受字符串+可选参数(搜索结果组成的数组+使返回结果附加偏移量+指定开始搜索的字符串位置)
preg_match_all()函数会返回整个正则表达式匹配的次数,$flags可以指定的参数有3个。
- PREG_PATTERN_ORDER:结果排序为$matches[0]保存完整模式的所有匹配,$matches[1]保存第一个子组的所有匹配,以此类推。
- PREG_SET_\ORDER:结果排序为$matches[0]包含第一次匹配得到的所有匹配(包含子组),$matches[1]是包含第二次匹配到的所有匹配(包含子组)的数组。
- PREG_OFFSET_CAPTURE:如果这个标记被传递,每个发现的匹配返回时都会增加它相对目标字符串的偏移量。
<?php
$pat='|<[^>]+>(.*)</[^>]+>|U';
$str='<b>example:</b><div align=left>This is a test.</div>';
preg_match_all($pat,$str,$out,PREG_PATTERN_ORDER);
print_r($out);
?>
//$flags参数对数组内容的影响
<?php
$pat='|<[^>]+>(.*)</[^>]+>|U';
$str='<b>example:</b><div align=left>This is a test.</div>';
preg_match_all($pat,$str,$out,PREG_SET_ORDER);
print_r($out);
?>
<?php
$pat='|<[^>]+>(.*)</[^>]+>|U';
$str='<b>example:</b><div align=left>This is a test.</div>';
preg_match_all($pat,$str,$out,PREG_OFFSET_CAPTURE);
print_r($out);
?>
preg_grep()
- 用于将数组中的元素与正则表达式匹配,返回所有匹配项组成一个数组。
preg_grep($pattern,$input,$flags)
//函数名+正则表达式+进行匹配的数组+可选参数(可设置为PREG_GREP_INVERT)
<?php
$arr=array(1,3,67,'s','56','hello','数组','PHP');
$res=preg_grep('/[0-9]+/',$arr);
print_r($res); //返回匹配元素组成的数组
echo '<br/>';
$res=preg_grep('/[0-9]+/',$arr,PREG_GREP_INVERT);
print_r($res); //返回不匹配元素组成的数组
?>
字符串处理函数strstr(),strpos(),strrpos()和substr()
1.strstr():返回字符串从指定字符串第一次出现的位置开始到结尾的字符串
strstr($haystack,$needle,$before_needle)
//函数名+字符串+指定字符串+可选参数(默认为TRUE,返回从指定字符串第一次出现开始位置的字符串)
<?php
$str='This is PHP!';
echo strstr($str,'is');
echo '<br/><br/>';
echo strstr($str,'is',TRUE);
echo '<br/><br/>';
var_dump(strstr($str,'to'));
?>
//如果想要指定不区分大小写的字符,就需要使用stristr()
2.strpos():返回指定字符在字符串中首次出现的位置。如果指定的值为一个整型数则会被当做字符的ASCII码来匹配字符串
strpos($haystack,$needle,$offset)
//函数名+字符串+指定字符串+可选参数(指定开始搜索的位置,默认值为0)
<?php
$str='This is PHP!';
echo strpos($str,'is');
echo '<br/><br/>';
echo strpos($str,'is',3);
echo '<br/><br/>';
var_dump(strpos($str,'to'));
?>
//在指定开始搜索的位置后,返回的值依然是以字符串开始为基准的
//如果想要指定不区分大小写的字符,就需要使用stripos()
//strrpos()函数用于反悔指定字符串在字符串中最后一次出现的位置
3.substr():用于返回字符串的子串,也就是返回从字符串中指定的字段
substr($string,$start,$length)
//函数名+字符串+指定开始位置+指定长度
在substr()语法中:
- 如果$start是非负数,返回的字符串将从$string的$start位置开始,从0开始计算。
- 如果$strat是负数,返回的字符串将从 string结尾处向前数第 start个字符开始。
- 如果$string的长度小于或等于$start,将返回FALSE。
- 如果提供了正数的$length,返回的字符串将从$start处开始最多包括$length个字符。
- 如果提供了负数的$length,那么$string末尾的许多字符将会被漏掉。
- 如果提供了0,FALSE或NULL的$length,那么将返回一个空字符串。
- 如果没有提供$length,返回的子字符串将从$start位置开始直到字符串结尾。
<?php
$res=substr('abcdef',0,-1);
echo $res.'<br/><br/>';
$res=substr('abcdef',2,-1);
echo $res.'<br/><br/>';
$res=substr('abcdef',4,-4);
echo $res.'<br/><br/>';
$res=substr('abcdef',0,-4);
echo $res.'<br/><br/>';
$res=substr('abcdef',-3,-1);
echo $res.'<br/>';
?>
替换字符串
- 对于一些比较复杂的字符串替换操作,可以通过正则表达式的替换函数preg_replace()来完成。
- 对字符串做简单的替换处理,从效率方面考虑,建议使用str_replace()。
str_replace()
- 用于替换字符串,它可以返回一个字符串或者数组。
str_replace($search,$replace,$subject,&$count)
//函数名+查找的目标(可以为数组)+替换值+执行替换的字符串或数组+可选参数(对替换次数进行计数)
<?php
$str='Hello World!';
$sea='World';
$rep='PHP';
$new_str=str_replace($sea,$rep,$str);
echo 'Before:'.$str;
echo '<br/><br/>';
echo 'After:'.$new_str;
?>
<?php
$str='Hello World!World!World!'; //重复替换
$sea='World';
$rep='PHP';
$new_str=str_replace($sea,$rep,$str);
echo 'Before:'.$str;
echo '<br/><br/>';
echo 'After:'.$new_str;
?>
//使用数组参数
<?php
$str='Hello World!';
$sea=array('Hello','World');
$rep=('Hi','PHP');
$new_str=str_replace($sea,$rep,$str);
echo 'Before:'.$str;
echo '<br/><br/>';
echo 'After:'.$new_str;
?>
//实际应用:将编程中常用的换行替换为浏览器中的换行
<?php
$str='Line1\nLine2\nLine3\n';
$sea=array('\r\n','\n','\r');
$rep='<br/>';
$new_str=str_replace($sea,$rep,$str);
echo 'Before:'.$str;
echo '<br/><br/>';
echo 'After:'.$new_str;
?>
//接受替换的字符串是数组时会出现的情况
<?php
$str=array('bule','red','yellow','green');
$new_str=str_replace('red','pink',$str);
echo 'Before:'.'<br/>';
print_r($str);
echo '<br/><br/>';
echo 'After:'.'<br/>';
print_r($new_str);
?>
//接受替换的字符和替换字符均为字符串时会出现的特殊情况
<?php
$str=array('Hello','World','!');
$sea=array('Hello','World');
$rep=array('Hi');
print_r(str_replace($sea,$rep,$str)); //从左到右依次替换,一一对应
?>
//多重替换
<?php
$str='A';
$sea=array('A','B','C','D','E');
$REP=array('B','C','D','E','F');
echo str_replace($sea,$rep,$str);
//str_replace()的替换要搜索完全部元素后才会停止。而不是替换一次就停止
?>
<?php
$str='a p';
$sea=array('a','p');
$rep=array('apple','pear');
echo str_replace($sea,$rep,$str);
?>
//&$count的运用
<?php
$str='google';
$sea='o';
$rep='*';
$new_str=str_replace($sea,$rep,$str,$count);
echo 'After:'.$new_str;
echo '<br/>';
echo 'Count:'.$count;
?>
preg_replace()
- preg_replace()与str_replace()的功能类似,最大的不同是preg_replace()使用正则表达式来匹配需要替换的字符串
preg_replace($pattern,$replacement,$subject,$limit=-1,$count)
//函数名+搜索模式+替换项+被替换字符串+可选参数(指定模式替换次数)+统计替换次数
<?php
$str='goooogle';
$sea='/o/';
$rep='*';
$new_str1=preg_replace($sea,$rep,$str);
echo 'After:'.$new_str1;
echo '<br/><br/>';
$new_str2=preg_replace($sea,$rep,$str,2);
echo 'After:'.$new_str2;
?>
//preg_replace()的典型使用示例
<?php
$pattern=array('/(19|20)(\d{2})-(\d{1,2})/','/^\s*{(\w+)}\s*=/');
$replace=array('\3/\4/\1\2','$\1=');
echo preg_replace($pattern,$replace,'{startDate}=2012-10-12');
?>
//替换字符串中多个空格为一个空格
<?php
$str='This is PHP !';
$new_str=preg_replace('/\s\s+/',' ',$str);
echo $new_str;
?>
分割和连接字符串
- 简单的分割可以使用explode()处理,复杂的分割可以使用正则表达式分割函数preg_split()处理。
- 字符串的连接除了点(.)之外,还可以使用implode()将字符串连接起来。
explode()
explode($separator,$string,$limit)
- explode()返回由字符串组成的数组,每个元素都是$string的一个子串,它们被字符串$separator作为边界点分割出来
- 如果$separator为空字符串(“”),explode()将返回FALSE;如果$separator所包含的值在$string中找不到,那么explode()将返回包含$string单个元素的数组。
<?php
$str='Hello PHP!';
print_r(explode('#','$str')); //使用不存在的分隔符
var_dump(explode('$str')); //分隔符为空
?>
- 如果设置了$limit参数,则返回的数组包含最多$limit个元素,而最后那个元素将包含$string的剩余部分。
- 如果$limit参数是负数,则返回除了最后的$limit个元素外的所有元素。
<?php
$str='one two three four';
print_r(explode(' ',$str,2));
print_r(explode(' ',$str,-2));
?>
//数组
<?php
$email='marshall@gmail.com';
$arr=explode('@',$email);
echo 'UesrName:'.$arr[0];
echo '<br/><br/>';
echo 'ServerName:'.$arr[1];
?>
preg_split()
- preg_split()通过一个正则表达式分割字符串,执行完毕后返回由被分割的字符串作为元素组成的数组。
preg_split($pattern,$subject,$limit,$flags)
//函数名+接受正则表达式+接受被分割的字符串+可选参数(控制分割得到的字符串元素个数+可以被设置为几个指定的值)
- $limit的值如果为-1,0或NULL时都代表“不限制”。
- $flags可以被指定为下面几个值或多个值得组合(以位或运算“|”组合).
PREG_SPLIT_NO_EMPTY:preg_split()将返回分隔符后的非空部分
<?php
$str='string';
$new_str1=preg_split('//',$str,-1);
$new_str1=preg_split('//',$str,-1,PREG_SPLIT_NO_EMPTY);
echo '不控制:';
print_r($new_str1);
echo '<br/><br/>';
echo '控制:';
print_r($new_str2);
?>
PREG_SPLIT_DELIM_CAPTURE:用于分隔的模式中的括号表达式将被捕获并返回
<?php
$pattern='/(19|20)(\d{2})-(\d{1,2})-(\d{1,2})/';
$replace='2012-10-12';
print_r(preg_split($pattern,$replace,-1,PREG_SPLIT_DELIM_CAPTURE));
?>
PREG_SPLIT_OFFSET_CAPTURE:对于每一个出现的匹配返回时将会附加字符串偏移量
<?php
$str='hypertext language programming';
$chars=preg_split('//',$str,-1,PREG_SPLIT_OFFSET_CAPTURE);
print_r($chars);
?>
implode()
- implode()用于把数组元素组合为一个字符串,它可以接受两个参数
implode($separator,$array)
//函数名+可选参数(用于连接元素的字符)+接受用于转换的数组
<?php
$arr=array('I','Love','PHP','!');
echo '直接连接:'.implode($arr);
echo '<br/><br/>';
echo '使用-连接:'.implode('-',$arr);
?>