正则表达式
一.正则表达式(regular expression)的概念:
正则表达式就是一套专门用于处理文本的强大工具,可以对进行文本查找,匹配,替换;
正则表达式常用于验证表单提交的内容,比如验证电话号码,Email地址,身份证号码等是否有效;
php支持两种风格的正则表达式:Perl风格 Posix 风格
Perl风格
PCRE全称为Perl Compatible Regular Expression,意思是Perl兼容正则表达式。
PCRE来源于Perl语言,而Perl是对字符串操作功能最强大的语言之一,PHP的最初版本就是由Perl开发的产品。
在PCRE中,通常将正则表达式 包含在两个反斜线
"/"
之间;
例:
"/apple/"
定界符也不仅仅局限于
"/"
。除了字母、数字和斜线
"\"以外的任何字符都可以作为定界符,像"
#
"、"
/
"、"
!"等都可以的。
Posix 风格
一般而言,实现相同的功能Perl风格的,效率高些,我们一般使用Perl风格的函数!
检查email地址的合法性
1.用字符串查找的方法:
function
is_email(
$email
)
{
$has_at
=
strpos
(
$email
,
"@"
);
//检查是否 包含@
$has_dot
=
strpos
(
$email
,
"."
);
//检查是否包含.
if
(
$has_at
&&
$has_dot
){
return
true;
}
else
{
return
false
}
}
echo
is_email(
"tom@php.net"
);
//true
echo
is_email(
"tom@php"
);
//false
2.使用正则表达式的方法:
function
is_email(
$email
){
return
preg_match(
'/^[a-zA-Z]+@[a-zA-Z]+\.[a-zA-Z]+$/'
,
$email
);
}
echo
is_email(
"tom@php.net"
);
//true
echo
is_email(
"tom@php"
);
//false
二、Perl 兼容正则表达式函数
1. preg_match() 进行正则表达式匹配
'/hello/'
进行匹配的模式
"hello world"
匹配的字符串
$res
将匹配的结果存放到一个变量里面
preg_match(
"/hello/"
,
"hello world"
,
$res
);
2. preg_match_all() 进行正则表达式全局匹配
preg_match_all(
"/h/"
,
"hello hello"
,
$res
);
//全匹配
3. preg_replace() 执行正则表达式的搜索和替换
"/hello/"
被匹配字符串的模式
"aaaaa"
用来匹配的字符串
"hello world"
从哪个字符串里面匹配
$res
= preg_replace(
"/hello/"
,
"aaaa"
,
"hello world"
);
var_dump(
$res
);
//aaaa world
4、preg_split() 用正则表达式分割字符串
'/ /'
用于搜索的模式, 字符串形式. 分隔符
$str
用于分割的字符串
$str
=
'hypertext hanguage hrogramming'
;
$chars
= preg_split(
'/ /'
,
$str
);
var_dump(
$chars
);
//array()
5、preg_grep() 返回与模式匹配的数组单元
"/111/"
匹配模式
$array
被匹配的元素
$array
=
array
(3324,111,222,33,44,55);
$fl_array
= preg_grep(
"/111/"
,
$array
);
var_dump(
$fl_array
);
array
(1) { [1]=> string(3)
"111"
}
三、POSIX 扩展正则表达式函数
1.
ereg
() 搜索跟正则表达式pattern匹配的一个字符串。区分大小写。搜索到返回true,否则返回false
"(hello)"
代表匹配模式
"hello world"
代表匹配字符串
$res
用来存放结果
ereg
(
"(hello)"
,
"hello world"
,
$res
);
var_dump(
$res
);
2.
eregi
()
eregi
()函数功能与
ereg
()相同,只是不区分大小写;
"(hello)"
代表匹配模式
"hello world"
代表匹配字符串
$res
用来存放结果
eregi
(
"(hello)"
,
"hello world"
,
$res
);
var_dump(
$res
);
3.
ereg_replace
() 搜索跟正则表达式pattern匹配的一个字符串,并用新的字符串代替所有这个表达式出现的地方
"(hello)"
代表替换模式
"aaaaa"
替换字符串
"hello world"
被替换的字符串
$res
=
ereg_replace
(
"(hello)"
,
"aaaa"
,
"hello world"
);
var_dump(
$res
);
//string(10) "aaaa world"
4.
eregi_replace
()
eregi_replace
()函数功能与
ereg_replace
相同,只是不区分大小写;
"(HELLO)"
代表替换模式
"aaaaa"
替换字符串
"hello world"
被替换的字符串
$res
=
eregi_replace
(
"(HELLO)"
,
"aaaa"
,
"hello world"
);
var_dump(
$res
);
//string(10) "aaaa world"
四.正则表达式的构成
1.模式
模式是正则表达式最基本的元素,它们是一组描述字符串特征的字符;
模式可以很简单,由普通的字符串组成, 也可以很复杂,包含很多的特殊字符;
验证身份证号码:
'/^[1-9][0-9]{14}([0-9]{2}[0-9xX])?$/'
验证手机号码:
'/^(13[0-9]|15[0-356]|18[025-9])\d{8}$/'
验证URL地址:
"^(http|ftp|https)://(www\.)?[a-zA-Z0-9\-]+\.(com|net|org|cn)$"
2.元字符(特殊字符)
* 匹配前面的字符零次或多次 等同于 {0,}
preg_match(
"/a*/"
,
"bbbbba"
,
$res
);
//array(1) { [0]=> string(0) "" }
+ 匹配前面的字符一次或多次 等同于 {1,}
preg_match(
"/a+/"
,
'bbbbbbbbbbaa'
,
$res
); string(2)
"aa"
? 匹配前面的字符零次或一次 等同于 {0,1}
preg_match(
"/a?/"
,
"aaaabbbb"
,
$res
);
//"a"
| 匹配两个或多个选择
preg_match(
"/(h|a)+/"
,
"dfghsssssasfgdsf"
,
$res
);
^ 匹配字符串的开始位置
preg_match(
"/^hello/"
,
"hello world"
,
$res
);
$ 匹配字符串结束位置
preg_match(
"/^hello world$/"
,
"hello world"
,
$res
);
\b 匹配单词的边界(如空格、横杠,但不包括下划线) *更简单点说 \b匹配特殊字符*
preg_match(
"/hello\b/"
,
"hello-world"
,
$res
);
\B 匹配除单词边界以外的部分 *更简单点说 \B匹配除了特殊字符以外的字符*
preg_match(
"/\Bc+/"
,
"aaaa - bbbb - aaac"
,
$res_test
);
[] 匹配方括号中的任一字符
preg_match(
"/[abcdf]/"
,
"aaaa - bbbb - aaac"
,
$res_test
);
[^] 匹配除方括号中的字符外的任何字符
preg_match(
"/[^abcdf]/"
,
"asd"
,
$res_test
);
{m} m 是一个非负整数。匹配确定的 m 次
preg_match(
"/\d+/"
,
"asdasdasdad 3434"
,
$res
);
{m,} m 是一个非负整数。至少匹配m 次
{m,n} 最少匹配 m次且最多匹配 n次
() 表示一个整体
. 匹配除换行之外的任何一个字符
3.预定义元字符
由于某些模式会反复用到,所以可以使用以下预定义类;
\d 匹配一个数字;等价于[0-9]
preg_match(
"/\d+/"
,
"asdasdasdad 3434"
,
$res
);
\D 匹配除数字以外任何一个字符;等价于[^0-9]
preg_match(
"/\D+/"
,
"asdasdasdad 3434"
,
$res
);
\w 匹配一个英文字母、数字或下划线;等价于[0-9a-zA-Z_]
preg_match(
"/\w+/"
,
"asdasdasdad 3434"
,
$res
);
\W 匹配除英文字母、数字和下划线以外任何一个字符;等价于[^0-9a-zA-Z_]
preg_match(
"/\W+/"
,
"asdasdasdad 3434"
,
$res
);
\s 匹配一个空白字符;等价于[\f\n\r\t\v]
preg_match(
"/\s+/"
,
"asdasdasdad 3434"
,
$res
);
\S 匹配除空白字符以外任何一个字符;等价于[^\f\n\r\t\v]
preg_match(
"/\S+/"
,
"asdasdasdad 3434"
,
$res
);
4.匹配字符的开始和结束
在某些情况下,需要对匹配范围进行限定,以获得更准确的匹配结果;
"^"
置于字符串的开始确保模式匹配出现在字符串首端;
"$"
置于字符串的结束,确保模式匹配出现字符串尾端。
如果不加边界限制元字符,将获得更多的匹配结果。
$res
= preg_match(
"/^hello/"
,
"hello world"
);
var_dump(
$res
);
$res
= preg_match(
"/world$/"
,
"hello world"
);
var_dump(
$res
);
5.匹配任意字符
用
"."
匹配除换行符外任何一个字符
$res
= preg_match(
'/./'
,
"something"
);
var_dump(
$res
);
通常可以使用
".*"
组合来匹配除换行符外的任何字符
6.匹配包含某个范围的字符
用
"[start-end]"
匹配包含某个范围的字符
[a-z] 匹配所有的小写字母
[A-Z] 匹配所有的大写字母
[a-zA-Z] 匹配所有的字母
[0-9] 匹配所有的数字
[0-9\.\-] 匹配所有的数字,句号和减号
$res
= preg_match(
"^[a-z]+$"
,
"abc"
);
var_dump(
$res
);
7.重复匹配
正则表达式中有一些用于重复匹配的元字符:
"?"
、
"*"
、
"+"
。他们主要的区
别是重复匹配的次数不同。
"?"
匹配前面的字符零次或一次 等同于 {0,1}
"*"
匹配前面的字符零次或多次 等同于 {0,}
"+"
匹配前面的字符一次或多次 等同于 {1,}
"{m}"
匹配确定的 m 次。 m 是一个非负整数;
"{m,n}"
最少匹配 m 次且最多匹配 n 次。 m 和 n 均为非负整数,其中m <= n;
"{m,}"
至少匹配m 次。 m 是一个非负整数;
8.匹配两个或多个选择
用圆括号
"(word1|word2|…)"
定义包含word1、word2、…的任意字符串的规则
$res
= preg_match (
'/^(this|the)/'
,
'this island is a beautiful land'
);
var_dump(
$res
);
9,模式修正符 : 模式修正符在正则表达式定界符之外使用。
i 在和模式进行匹配时不区分大小写
preg_match(
"/hello/i"
,
"HELLO WORLD"
,
$res
);
m 将字符串视为多行
$str
= 'bcd
abc
cba';
preg_match_all(
'/^abc/m'
,
$str
,
$arr
);
print_r(
$arr
);
s 模式中的圆点元字符 “ . “将匹配所有的字符,包括换行符
$str
= 'adsadsa
c';
preg_match_all(
'/a.*c/s'
,
$str
,
$arr
);
print_r(
$arr
);
x 模式中的空白忽略不计,除非已经转义
preg_match_all(
"/^ hello /x"
,
"hello"
,
$res
);
U 取消贪婪匹配
$pattern
=
'/<b>.*<\/b>/U'
;
$string
=
'<b>welcome</b> <b>to</b> <b>phpfuns</b>'
;
preg_match(
$pattern
,
$string
,
$res
);
$str
=
'21PhP8'
;
//不区分大小写
$preg
=
'/php/i'
;
//拿到所有匹配的
$res
= preg_match(
$preg
,
$str
);
var_dump(
$res
);
练习:
1.分析email地址的规则,写一个函数,用于验证email地址;
2.分析电话号码的规则,写一个函数,用于验证电话号码;
</b>