Skip to main content

PHP之正则表达式

一、正则表达式的产生

美国新泽西州的Warren McCulloch和出生在美国底特律的Walter Pitts这两位神经生理方面的科学家,研究出了一种用数学方式来描述神经网络的新方法,他们创造性地将神经系统中的神经元描述成了小而简单的自动控制元,从而作出了一项伟大的工作革新。随后,发现可以将这一工作应用于使用 Ken Thompson 的计算搜索算法的一些早期研究,Ken Thompson 是 Unix 的主要发明人。

正则表达式的第一个实用应用程序就是 Unix 中的 qed 编辑器。

正则表达式,又称规则表达式,(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。

二、应用范围

  • 手机输入法
  • 文件、文字搜索
  • 手机号、邮箱验证
  • 爬虫标签匹配

三、PHP正则函数

1.preg_match()和preg_match_all()

 preg_match($pattern,$subject,[array & $matches]) :
    仅仅匹配一次,搜索subject与pattern给定的正则表达式的一个匹配,返回值0或者1,参数放到一个数组里面去,第三个参数为可选。
  preg_match_all($pattern,$subject,array & $matches): 
    匹配多次的所有,返回所有的次数,放到$matches二维数组(执行一个全局的搜索),第三个参数为必选。

代码试验一下:

$pattern="/[0-9]/";
$subject = 'adjf3274987jaidjf873rji23j';
$ma1 = $ma2 = array();
$t1 = preg_match($pattern,$subject,$ma1);
$t2 = preg_match_all($pattern,$subject,$ma2);
var_dump($ma1);
echo '<hr/>';
var_dump($ma2);

返回结果:

array(1) { [0]=> string(1) “3” }


array(1) { [0]=> array(12) { [0]=> string(1) “3” [1]=> string(1) “2” [2]=> string(1) “7” [3]=> string(1) “4” [4]=> string(1) “9” [5]=> string(1) “8” [6]=> string(1) “7” [7]=> string(1) “8” [8]=> string(1) “7” [9]=> string(1) “3” [10]=> string(1) “2” [11]=> string(1) “3” } }

2.preg_replace()和preg_filter()

preg_replace($pattern,$replacement,$subject):
   执行一个正则表达式的搜索和替换,会保留未匹配的和匹配替换的数据
preg_filter($pattern,$replacement,$subject);
   执行一个正则表达式搜索和替换,仅仅返回匹配并替换的结果

区别点:preg_replace()和preg_filter()功能基本一致,只不过在$subject为数组时,两个函数返回的数据不一样。

第一个会保留未匹配的和匹配替换的数据,第二个只会保留 匹配替换的数据,都是以数组形式保存,如果$subject为字符串时,返回结果是替换后的字符串,当$subject为数组时,数组的键值会被一一匹配,匹配一次算一次。

代码走起:

//php的字符串替换preg_repalce和preg_filter
echo '<hr/>';
$pattern=array('/[0123]/','/[456]/','/[789]/');
$subject = array('wenu','r3ui','76as83','s',' 0ck9');
$replacement=array('新','生活','啦');
$t1 = preg_replace($pattern,$replacement,$subject);  //返回数组,可以分组对应的匹配数据
$t2 = preg_filter($pattern, $replacement, $subject);  //返回数组,保留发生了替换的字符串
var_dump($t1);
echo '<hr/>';
var_dump($t2);

结果如下:

array(5) { [0]=> string(4) “wenu” [1]=> string(6) “r新ui” [2]=> string(17) “啦生活as啦新” [3]=> string(1) “s” [4]=> string(9) ” 新ck啦” }


array(3) { [1]=> string(6) “r新ui” [2]=> string(17) “啦生活as啦新” [4]=> string(9) ” 新ck啦” }

3. preg_grep()和preg_split()

preg_split($pattern,$subject):
    通过一个正则表达式分隔字符串,把匹配结果放到$array数组,过滤不合适的
preg_grep($pattern,array $input):
    返回匹配模式的数组条目,只匹配,不替换

代码走起:

//字符匹分割数组preg_grep,用于过滤出匹配数据
$pattern='/[0-9]/';
$subject=array('dfg','gd2','fasd1');
$smarty=preg_grep($pattern, $subject);
var_dump($smarty);

//字符截成数组preg_split,正则分割字符串成数组
echo '<hr/>';
$pattern='/[0-9]/';
$subject='我1吃2西瓜3月4?';
$preg=preg_split($pattern,$subject);
var_dump($preg);

返回结果:

array(2) { [1]=> string(3) “gd2” [2]=> string(5) “fasd1” }


array(5) { [0]=> string(3) “我” [1]=> string(3) “吃” [2]=> string(6) “西瓜” [3]=> string(3) “月” [4]=> string(3) “?” }

4.preg_quote()

 preg_quote($str)
     把正则运算符转义为\内容,需要参数 str 并向其中 每个正则表达式语法中的字符前增加一个反斜线。

代码如下:

$str='faf{s}fs[er]gr';
$atring=preg_quote($str);
var_dump($atring);

结果如下:

string(18) “faf\{s\}fs\[er\]gr”

PHP函数总结:

1.都是以preg_开头,除了preg_quote函数外,所有的函数的第一个参数都是正则匹配对象
1.preg_match()应用于表单验证,正确是1,错误是0
3.preg_replace()用于非法词语的过滤

 

四、正则基本语法

1.基本语法

界定符:/[0-9]/或者#[0-9]#或者{[0-9]}
正则表达式工具:regexpal, 使用这个工具不包含界定符

2.原子以及筛选方式

原子是正则表达式最小的单位,分为可见原子,不可见原子
可见原子,unicode编码表里面使用键盘输出后肉眼可见的字符,如标点符号,汉字,文字,英文,物理花字符等
不可见原子,unicode编码表里面使用键盘输出后肉眼看不见的字符,如换行符,回车,空格
可见原子:

<  <
>  >
$  \$
-  \-
+  \+
*  \*
\  \\

不可见原子:

空格       空格
制表符    \t
回车      \n字符
下一行制表符  \n\t

3.筛选方式

|             匹配两个或者多个分支选择
[]          匹配方括号的任意一个原子 [Dd]duang
[^]       匹配除了方括号 原子之外的任意字符
[a-z]    a-z的字母
[A-Z]  A-Z的字母
[n-n] 支持区间的选择 [1-5] [a-c] [a-zA-Z0-9]

4.原子集合

.   匹配除换行符之外的任意字符,即[^\n]
\d 匹配任意一个十进制数字,即[0-9]
\D 匹配任意一个非十进制数字,即[^0-9]
\s 匹配一个不可见原子,即[\f\n\r\t\v]
\S 匹配一个可见原子,即[^\f\n\r\t\v]
\w 匹配任意一个数字、字母或者下划线,即[0-9a-zA-Z_]
\W 匹配任意一个非数字、字母或者下划线,即[^0-9a-zA-Z_]

5.量词

{n} 匹配前面原子恰好出现n次
{n,} 匹配前面原子最少n次
{n, m}匹配前面原子最少n次,最多m次
* 匹配前面原子任意次 (出现0次,或者出现n次),即[0,]
? 匹配前面原子0次或一次,即[0,1]
+ 匹配至少一次,也就是一到无穷大次,即{1,}

6.边界控制

^ 匹配字符串开始的位置 匹配前不可是空,否则无法匹配
$ 匹配字符串结尾的位置
() 匹配其中的整体作为一个原子
\A 匹配指定字符串作为开始
\Z 匹配指定字符串作为结尾

7.模式单元

()
(D|d)uang
举例:匹配Duang ~ duang ~
[Dd]duang~或者Duang ~ | duang ~

8.修正模式

贪婪匹配:匹配结果存在歧义的时候取其长
懒惰匹配:匹配结果存在歧义的时候取其短
默认是贪婪模式,懒惰模式就是在最后的正则表达式后面是放一个大写的U
U 懒惰匹配
i 忽略英文字母小写
x 忽略空白
s 让元字符‘.’匹配包括换行符在内的所有字符

 

上代码:

$pattern='/xinxin.+123/Uix';
$subject='I love xinxin___123123123';
$mathes=array();
preg_match($pattern, $subject,$mathes);
var_dump($mathes);

结果:

array(1) { [0]=> string(12) “xinxin___123” }

总结:由于使用了U懒惰匹配,才匹配出来最短数据,默认是贪婪匹配,不信可以试试额。

五、正则实战

1.非空匹配

.+

2.浮点数匹配(两位小数)

 \d+\.\d{2}$

3.手机号匹配

 1(3|5|7|8|4)\d{9}

4.邮箱匹配

^\w+(\.\w+)*@\w+(\.\w+)+$

5.url匹配

^(https?://)?(\w+\.)+(a-zA-Z)+$

 

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

18 − 13 =