《PHP之正则表达式系统总结》

为什么选择PHP语言来写正则表达式这篇博客呢?嘿嘿嘿,因为PHP正则表达式稍微懂一点,如果是其它语言的正则表达式,都是差不多的。
一、正则表达式函数解析
PHP中常用的正则表达式函数:

int preg_match($pattern, $subject);
preg_match_all($pattern, $subject, array &$matches);
preg_replace($pattern, $replacement, $subject);
preg_filter($pattern, $replacement, $subject);
preg_grep($pattern, array $input);
preg_split($pattern, $subject);
preg_quote($str);

参数说明:
pattern= subject = 匹配的目标数据
1,preg_match(pattern, subject, [array &matches]);pregmatchall( pattern, subject, array & matches);
注意:preg_match()的第三个参数是可选的,后边那个函数的第三个参数是必选的。注意那个&,表示按引用传递
preg_match()在匹配subject subject中所有符合pattern matches数组中.这两个函数都有一个整形的返回值,即匹配到的次数。

//需要数据输出调试的时候,我们就用这个写好的show函数
function show($var = null){
    if(empty($var)){
        echo 'null';
    }elseif (is_array($var)||is_object($var)) {
        //array,object
        echo '<pre>';
        print_r($var);
        echo '</pre>';

    }else{
        //string,int,float
        echo $var;
    }
}

/*
1,preg_match($pattern, $subject, [array &$matches]);和preg_match_all($pattern, $subject, array &$matches);
*/
$pattern = '/[0-9]/';//表示匹配0到9之间的数字
$subject = '45ghghg545hg5jh';
$m1 = $m2 = array();
$t1 = preg_match($pattern, $subject, $m1);
$t2 = preg_match_all($pattern, $subject, $m2);
show($m1);
echo '<hr />';
show($m2);
echo ‘<hr />’;
show($t1.’||’.$t2);

执行结果:
这里写图片描述
我会回看见preg_match()返回的是一位数组,而preg_match_all()返回的是一个二维数组
2,preg_replace(pattern, replacement, subject)pregfilter( pattern, replacement, subject)
这两个函数的功能极其的相似,参数完全相同,只是返回结果有一点点的区别。当使用pattern subject中进行匹配,匹配的结果会替换成$replacement.(说到这个替换功能,小伙伴们有必要将str_replace()函数复习一下http://www.w3school.com.cn/php/func_string_str_replace.asp

$pattern = '/[0-9]/';//表示匹配0到9之间的数字
$subject = '45ghghg545hg5jh';
$replacement = "^_^";

$str1 = preg_replace($pattern, $replacement, $subject);
$str2 = preg_filter($pattern, $replacement, $subject);

show($str1);
echo '<hr />';
show($str2);

执行结果:
这里写图片描述
我们都知道搜索目标和替换的数据两个变量,不仅仅支持字符串,还支持数组,preg_replace()也是支持数组替换的

$pattern = array('/[0123]/', '/[456]/', '/[789]/');
$subject = '1ghghg45hg8jh';
$replacement = array('^_^', '*_*', '$_$');//表示当匹配到0123中的任意一个数字时,就替换成^_^.如果匹配到456中的任意一个数字就替换成*_*

$str1 = preg_replace($pattern, $replacement, $subject);
$str2 = preg_filter($pattern, $replacement, $subject);

show($str1);
echo '<hr />';
show($str2);

执行结果:
这里写图片描述
到现在我们还是没有看到两个函数返回值饿区别在哪里,现在,我们把$subject也换成数组

$pattern = array('/[0123]/', '/[456]/', '/[789]/');
//$subject = '1ghghg45hg8jh';
$subject = array('were', 't4bd', '9fdfdgd', 'r', '1df');
$replacement = array('^_^', '*_*', '$_$');//表示当匹配到0123中的任意一个数字时,就替换成^_^.如果匹配到456中的任意一个数字就替换成*_*

$str1 = preg_replace($pattern, $replacement, $subject);
$str2 = preg_filter($pattern, $replacement, $subject);

show($str1);
echo '<hr />';
show($str2);

执行结果:
这里写图片描述
这个时候我们就看到区别了,第一个函数会将数组中没有与$pattern匹配的字符串也保存在数组中,而第二个函数只将匹配到的字符串保存在数组中,输出来
3,preg_grep(pattern,array input)
他就是将匹配到的字符串保存到数组中,然后返回出来,不进行匹配

$pattern = '/[0-9]/';//表示匹配09之间的数字
//$pattern = array('/[0123]/', '/[456]/', '/[789]/');
//$subject = '1ghghg45hg8jh';
$subject = array('were', 't4bd', '9fdfdgd', 'r', '1df');
//$replacement = array('^_^', '*_*', '$_$');//表示当匹配到0123中的任意一个数字时,就替换成^_^.如果匹配到456中的任意一个数字就替换成*_*

$arr = preg_grep($pattern, $subject);

show($arr);

执行结果:
这里写图片描述
4,preg_split(pattern, subject)
通过pattern subject字符串,然后把分割得到的多个字符串放置到数组中返回出来(说到分割,大家就会想到explode()函数,那么小伙伴们有必要回忆一下http://www.w3school.com.cn/php/func_string_explode.asp

$pattern = '/[0-9]/';//表示匹配09之间的数字
//$pattern = array('/[0123]/', '/[456]/', '/[789]/');
//$subject = '1ghghg45hg8jh';
$subject = 'shu3lv,5together';
//$replacement = array('^_^', '*_*', '$_$');//表示当匹配到0123中的任意一个数字时,就替换成^_^.如果匹配到456中的任意一个数字就替换成*_*

$arr = preg_split($pattern, $subject);

show($arr);

执行结果:
这里写图片描述
5,preg_quote($str)
将一个字符串中的正则表达式运算符进行转义
转义主要是为了防止运算符和我们要输出的字符串发生混淆,在正则表达式中,有这些运算符(.+*?[^]$(){}=!<>|:-),在正则表达式中直接书写这些字符,PHP的解析器会将它当做一个正则的运算符来看待,有的时候,比如我想匹配一个{},但是这个{}又是正则表达式中的一个运算符,这个时候我们就需要在前边加一个\进行转义,告诉PHP的解析器不要产生混淆

$str = "jhj{dfg}[5455]";

$arr = preg_quote($str);

show($arr);

执行结果:
这里写图片描述
总结:总结一下这几个PHP正则表达式中的几个函数
1,都是以preg_开头
2,除了preg_quote()函数外,第一个参数都是正则表达式
3,preg_match() 通常用于表单验证,如果匹配到,返回1 ,否则返回0
4,preg_replace()通常用于非法词语过滤等
二、正则表达式基本语法
概述:
1,界定符
2,原子
3,量词
4,边界控制
5,模式单元
(1)界定符
表示正则表达式开始和结束的位置 比如 $pattern = ‘[0-9]\’ 有两个斜杠将表达式夹在中间(它不是正则表达式的组成部分,它只是告诉PHP解析器,正则表达式是从什么时候开始和什么时候结束的)(其实也可以用#[0-9]#、{[0-9]},为了避免产生歧义,大家还是使用[0-9]\的方式)
福利:为了学习正则表达式的简单和方便,这里就推荐一个辅助书写正则表达式的神器:regexpal,这个是用html和css开发的,直接在浏览器中打开就能运行(http://wpjam.qiniudn.com/tool/regexpal/)
这里写图片描述
(2)原子
原子是正则表达式中最小的匹配单位,通常它只是Unicode编码表中的某一个字符。原子分为可见原子和不可见原子
**可见原子:**Unicode编码表中,用键盘输出后肉眼可见的字符 例如:标点、英文字母数字、汉子、日文、法文、数理化公式符号等等
**不可见原子:**Unicode编码表中,用键盘输出后肉眼看不见的字符 例如:换行符(\n)、回车(\r)、制表符(\t)、空格等等。正则表达式同样可以匹配到这些不可见原子
这里写图片描述
由于在匹配中文的时候可能会由于编码的问题,出现一些未知的错误,所以我们可以将中文转换成Unicode编码,编码转换工具:http://tool.chinaz.com/tools/unicode.aspx
这里写图片描述
当我们要匹配的符号是一个正则表达式的符号时,在前边加一个’\’进行转义就可以匹配到了
上边说的这些都是可见原子,下边我们说一下不可见原子
我们在regexpal工具中直接输入空格就行,就可以匹配到空格。匹配制表符,输入’\t’即可。
下边我们说一下:元字符(它主要做两件事,1,定义原子的筛选方式,2,将比较类似的原子进行归类,给出一个缩写来简化正则表达式 比如英文字符数字 用\w)
原子的筛选方式:(1)| 匹配两个或者多个分支选择(2)[] 匹配方括号中的任意一个原子(3)[^] 匹配除方括号中的原子之外的任意字符
这里写图片描述
如果想使用 | 的方式匹配到Duang~和duang~,这样写 Duang~|duang~ ,|是对两边的整串字符拿来匹配,而不是拿某一个来匹配(上边这几个元字符大家都用那个工具试一下,我就不一一截图了)
原子的集合:
. 匹配除换行符之外的任意字符
\d 匹配任意一个十进制数字,即[0-9]
\D 匹配任意一个非十进制数字,即[^0-9]
\s 匹配一个不可见原子,即[\f\r\t\n\v]
\S 匹配一个可见原子,即[^\f\r\t\n\v]
\w 匹配任意一个数字、字母或下划线,即[0-9a-zA-Z]
\W 匹配任意一个数字、字母或下划线,即[^0-9a-zA-Z]
大家可以使用上边那个工具来尝试一下
(3)量词
{n}表示其前边的原子恰好出现n次
{n,} 表示其前边的原子最少出现n次
{n,m}表示其前边的原子最少出现n次,最多出现m次
*表示匹配0次、1次或者多次其前边的原子,即{0,}
+表示匹配1次或者多次其前边的原子,即{1,}
? 表示匹配0次或1次其前边的原子,即{0,1}
大家给这几个拿去多练就好了
(4)边界控制和模式单元
^ 匹配字符串开始的位置
$ 匹配字符串结束的位置
() 匹配其中的整体为一个原子
看例子来说明:
这里写图片描述
那个$也是同理
那么模式单元的()是如何使用呢,假设我要匹配Duang~ duang~
这里写图片描述
到这里,正则表达式的基本语法就说完了,后边会有综合实例来进行巩固
三、正则表达式中的修正模式
1,贪婪匹配
匹配结果存在歧义时取其长
看下边的代码:

$pattern = '/shulv.+123/';//这个就是说,匹配以shulv开头,后边跟除换行符外的任意字符,且该字符出现1次或多次,并且以123结尾
$subject = 'I love shulv_123123123123123';
//当我们匹配到这个字符串的时候,我们发现,匹配到shulv_123可以,匹配到shulv_123123123123123也可以,这个时候就出现了歧义,这个时候,默认的使用的是贪婪模式,也就是匹配到最长的那个
$matches = array();

preg_match($pattern, $subject,$matches);

show($matches);

执行结果:
这里写图片描述
2,懒惰匹配
匹配结果存在歧义时取其短
还是上边的例子,如果我们想使用懒惰模式,可以直接在patternU pattern = ‘/shulv.+123/U’;
这个时候匹配到的结果就是shulv_123

常见修正模式:
U 懒惰匹配
u 贪婪匹配
I 忽略英文字母大小写
x 忽略空白
s 让元字符’ . ’匹配包括换行符在内的所有字符
这几个,小伙伴们自行练习
注意:如果你想让两种修正模式同时使用,可以这样写 ‘/ShUlv.+123/Ui’;这样就可以既忽略大小写,又使用懒惰模式

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章