简述正则表达式
正则表达式是什么?
正则表达式就是描述字符串排列模式的一种自定义语法规则。正则表达式就是通过构建具有特定规则的模式,和输入字符串信息进行比较,然后进行分割、匹配、查找、替换等等的相关操作。正则表达式不是PHP中独有的,多种语言均可以使用正则表达式,在这里我们介绍正则在PHP中的用法。
使用场合
1. PHP中,如果可以用字符串处理函数完成的任务,我们就不要使用正则表达式。
2. 有一些复杂的操作,例如格式检验等等,只能用正则表达式完成。
3. 正则表达式也是一个字符串,但是它是具有特殊意义的字符串。
4. 它具有一些编写规则,也是一种模式,也可以把它看做一种编程语言。
5. 只有把正则表达式运用到某个函数中使用,才能发挥出正则表达式的作用,否则,它便是一个简单的字符串。
小例子
图片的匹配例子
这就是匹配HTML中的一个图片标签,例如可以匹配
PHP中的正则表达式函数库
在PHP中,有两套正则表达式函数库。
1.POSIX 扩展的正则表达式函数(ereg_)。
2.Perl 兼容的正则表达式函数(preg_)。
Perl 兼容的函数库是后加的函数库,功能更加强大,另外JavaScript 和 Perl 语言里面也会兼容这种模式,所以推荐学习 Perl 语言兼容的函数库。
在学习时,我们就需要学习下面两点
1. 正则表达式的语法
2. PHP中正则表达式的处理函数
正则表达式的语法
任何正则表达式都是由定界符号、原子、元字符、模式修正符号四部分来组成的。下面我们以上面的例子依次来介绍这四部分内容。
1. 定界符号
除了字母,数字和反斜杠 \ 以外的所有字符均可以为定界符。上面的例子中,开头和末尾的两个斜线 / 便作为定界符,我们还可以利用其它字符来定义,例如 | |,{ },# #等等,不过我们一般是使用斜线 / 作为定界符。
2. 原子
上面的例子中,img \s 均为原子。原子是正则表达式的最基本的组成单位,而且必须至少包含一个原子,正则表达式中可以单独使用的字符,就是原子。
使用时注意事项总结如下
1)原子包括所有打印字符和非打印字符,打印字符就是我们可以在屏幕上看到的字符例如abc等等,非打印字符就是我们看不到的字符,例如空格,回车等等。
2)\. \* \+ \? \< \( \< \>,所有有意义的字符,如果想作为原子使用,必须统统使用 \ 转义字符转义。
3)转义字符 \ 可以将有意义的字符转为有意义的字符,例如 * 是元字符,代表匹配一个字符零到多次,但是 \* 就代表了 * 这个字符。
4)另外转义字符还可以将没有意义的字符转成有意义的字符,例如 \d 可以表示任意一个十进制数字。总结如下:
\d:表示任意一个十进制的数字。
\D:表示任意一个除数字以外的字符。
\s:表示任意一个空白字符,如空格、回车、\t、\n
\S:表示任意一个非空白
\w:表示任意一个字,包括 a-z,A-Z,0-9,下划线_
\W:表示任意一个非字,\w 之外的任意一个字符
5)自定义原子表,定义一个中括号,表示匹配中括号中的任何一个内容,注意是任何一个。例如
正则表达式 “/[123]/” 和字符串 “abc2″可以匹配成功。
正则表达式 “/[a-z]/” 和字符串 “x3″可以匹配成功。
正则表达式 “/[1-3a-z]/” 和字符串 “x”可以匹配成功。
在这里[^]中括号里面写入^代表取反,表示除了原子表中的原子,但是^必须写在[]的第一个字符上。例如
[^a-z]代表除了a-z的所有字符
[^\n\t]代表除了换行和制表的所有字符
3. 元字符
上面的例子中,* ?均为元字符。元字符就是用来修饰原子的字符,不可以单独出现。
例如 * 代表匹配前面的原子零到多次,但如果想匹配 *,则必须要加转义号 \* 来表示
,特殊地,. 点也可以表示原子
元字符总结分类如下
1)* 表示其前面的原子可以出现 0 至多次
2)+ 表示前面的原子可以出现 1 至多次,即至少一个原子
3)? 表示前面的原子可以出现 0 次或 1 次
4){ } 用于自己定义前面原子出现的次数,另外分为以下几种
{m},m表示一个整数,则前面的数字必须出现m次
{m,n},m,n表示两个整数,m<n,表示前面出现的原子最少出现 m 次,最多出现 n 次。
{m,} m表示一个整数,表示最少出现 m 次,最多无限
所以 * 可以表示为 {0,},+ 可以表示为{1,},? 表示为 {0,1}
5). 默认情况下,表示除换行符外任意一个字符,和 * 组合表示可以匹配任意字符串,和 + 组合表示至少一个字符串
6)^ 直接在一个正则表达式的第一个字符出现,表示字符串必须以这个正则表达式开始,例如
^okay,表示字符串必须以 okay 开头
7)$ 直接在一个正则表达式的最后一个字符出现,则表示字符串必须以这个正则表达式结尾,例如
okay$,表示字符串必须以 okay 结尾。
注意:^okay$只是匹配一个okay字符,若要匹配 okay 开头okay结尾,则正则表达式可以写为 ^okay.*okay$
8)| 表示或的关系,它的优先级是最低的,最后考虑它的功能
9)\b 表示一个边界,例如
字符串 this is island,那么 \bis\b 则可以匹配,它匹配的是中间的 is,is两边是有边界的。
10)\B 表示一个非边界,例如
\Bis\b,则匹配第一个is,\bis\B则匹配第三个 is
11)() 括号,重点,作用总结如下
(1)将括号里面的元素作为一个大原子使用
即作为一个整体使用,例如 (abc)+,可以匹配abcabc….
(2)改变优先级
加上括号可以提高其优先级别。
(3)作为子模式使用
正则表达式中添加括号相当于添加了子模式。全部匹配作为一个大模式,放到数组的第一个元素中,每个()是一个子模式按顺序放到数组的其它元素中去。
在下面所说的 preg_match 方法中,结果会被赋值到 $arr 变量中,先匹配外层模式,再匹配内层模式。
|
//正则表达式模式
//需要和上面模式字符串进行匹配的变量字符串
{
;
}
|
结果
(4)取消子模式
就将它作为大原子或者改变优先级使用。
只要在模式前面加一个 ?: 就可以取消子模式,例如
|
//即不把(am|pm)作为一个子模式,直接将 am|pm 看做一个整体来使用。
|
(5)反向引用
可以在模式中直接将子模式取出来,再作为正则表达式模式的一部分, 如果是在正则表达式像替换函数preg_replace函数中, 可以将子模式取出, 在被替换的字符串中使用
\1 取第一个子模式、 \2取第二个子模式, …. \5 (注意是单引号还是双引号引起来的正则)
“\\1″ 在双引号引起来的正则,它是可以解释转义字符的,所以 \1 必须要写成 \\1
‘\1′ 在单引号引起来的正则中,则不会出现这种情况,\1 仍然可以写成 \1
例如
|
//正则表达式模式
//需要和上面模式字符串进行匹配的变量字符串
{
;
;
;
}
|
在上面的例子中,因为(\W)已经匹配了第一个斜杠/,它已经作为第一个子模式保存起来了,我们想继续使用这个匹配,我们就可以用 \\1 来表示,如果是单引号引起来的正则,则直接用 \1 来表示就可以了,后面的 \\2 和它是同样的原理。
4. 模式修正符号
上面的例子中,最后 / 后面的 i u 即为模式修正符号。
1)就是几个字母
2)可以一次使用一个,每一个都具有一定的意义,也可以连续使用多个符号
3)放在最后面,是对整个正则表达式调优用的,也可以说是对正则表达式功能的扩展。
归类如下:
i:表示在和模式进行匹配时不区分大小写
m:将每一行字符视为新的一行,也就是换行符后任何一行都可以当做一个整体字符串,主要的影响就在于 ^ 号和 $ 号。
例如:
|
'/^abc/m'
'cde
abcd
efg'
//可以匹配成功,因为加入m之后,第二行的abcd也当做一行了,也算是以abc开头
|
s:如果没有使用这个模式修正符号,那么 “.” 是不能当做换行符的,加入s,将字符串视为单行,那么 “.” 也就可以表示换行符了。
x:模式中的空白忽略不计,注意是模式中的。
|
'/a b c/x'
'abc'
//可以匹配成功,因为加入x之后,a b c直接当做abc来看
|
e:正则表达式必须使用在 preg_replace 函数中使用
A:必须以正则表达式开头,也就相当于前面加了 ^
Z:必须以正则表达式结尾,相当于后面加了 $
U:取消贪婪模式,或者 .*? 也可以取消贪婪模式,不过两个同时使用时会导致相反的结果,相当于负负得正的影响,同时出现则会又开启了贪婪模式 。
综上所述,正则表达式的组成为
/原子和元字符/模式修正符号,其中 / 为定界符号,不过有一些语言是不需要这个定界符的,例如 Python 等。
5.元字符的优先级(了解)
1)\ 转义符最高
2)(),(?:),{ },括号其次
3)* + ? {}
4)^ $ \b
5)|
6.常用的正则表达式
1)校验数字的表达式
1 数字:^[0-9]*$
2 n位的数字:^\d{n}$
3 至少n位的数字:^\d{n,}$
4 m-n位的数字:^\d{m,n}$
5 零和非零开头的数字:^(0|[1-9][0-9]*)$
6 非零开头的最多带两位小数的数字:^([1-9][0-9]*)+(.[0-9]{1,2})?$
7 带1-2位小数的正数或负数:^(\-)?\d+(\.\d{1,2})?$
8 正数、负数、和小数:^(\-|\+)?\d+(\.\d+)?$
9 有两位小数的正实数:^[0-9]+(.[0-9]{2})?$
10 有1~3位小数的正实数:^[0-9]+(.[0-9]{1,3})?$
11 非零的正整数:^[1-9]\d*$ 或 ^([1-9][0-9]*){1,3}$ 或 ^\+?[1-9][0-9]*$
12 非零的负整数:^\-[1-9][]0-9″*$ 或 ^-[1-9]\d*$
13 非负整数:^\d+$ 或 ^[1-9]\d*|0$
14 非正整数:^-[1-9]\d*|0$ 或 ^((-\d+)|(0+))$
15 非负浮点数:^\d+(\.\d+)?$ 或 ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$
16 非正浮点数:^((-\d+(\.\d+)?)|(0+(\.0+)?))$ 或 ^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$
17 正浮点数:^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$ 或 ^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$
18 负浮点数:^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$ 或 ^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$
19 浮点数:^(-?\d+)(\.\d+)?$ 或 ^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$
2)校验字符的表达式
1 汉字:^[\u4e00-\u9fa5]{0,}$
备注:
Warning:preg_match() [<a href='function.preg-match'>function.preg-match</a>]: Compilation failed: PCRE does not support \L, \l, \N , \U , or \u at offset 3
错误提示:
<b>Warning</b>: preg_match() [<a href='function.preg-match'>function.preg-match</a>]: Compilation failed: PCRE does not support \L, \l, \N, \U, or \u at offset 3 in <b>D:XXX.php</b> on line <b>25</b><br />
错误原因:
preg_match("/^[\u4e00-\u9fa5]{1,4}$/",$str);
在使用上述代码匹配汉字时,出现如题错误。
测试1:
preg_match("/^[\u4e00-\u9fa5]{1,4}/",$str);
去掉结尾的“$”,错误依旧。
测试2:
preg_match("/^[\x4e00-\x9fa5]{1,4}/",$str);
将u改为“x”,错误消失,但是匹配失败。
测试3:
preg_match("/^[\x{4e00}-\x{9fa5}]{1,4}/",$str);
加上大括号,错误提示:
<b>Warning</b>: preg_match() [<a href='function.preg-match'>function.preg-match</a>]: Compilation failed: character value in \x{...} sequence is too large at offset 9 in <b>D:XXX.php</b> on line <b>25</b><br />
测试4:
preg_match("/^[\x{4e00}-\x{9fa5}]{1,4}/u",$str);
加入参数u,错误消失,匹配正确。
|
2 英文和数字:^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$
3 长度为3-20的所有字符:^.{3,20}$
4 由26个英文字母组成的字符串:^[A-Za-z]+$
5 由26个大写英文字母组成的字符串:^[A-Z]+$
6 由26个小写英文字母组成的字符串:^[a-z]+$
7 由数字和26个英文字母组成的字符串:^[A-Za-z0-9]+$
8 由数字、26个英文字母或者下划线组成的字符串:^\w+$ 或 ^\w{3,20}$
9 中文、英文、数字包括下划线:^[\u4E00-\u9FA5A-Za-z0-9_]+$
10 中文、英文、数字但不包括下划线等符号:^[\u4E00-\u9FA5A-Za-z0-9]+$ 或 ^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$
11 可以输入含有^%&’,;=?$\”等字符:[^%&’,;=?$\x22]+
12 禁止输入含有~的字符:[^~\x22]+
3)特殊需求表达式
1 Email地址:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
2 域名:[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?
3 InternetURL:[a-zA-z]+://[^\s]* 或 ^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$
4 手机号码:^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$
5 电话号码(“XXX-XXXXXXX”、”XXXX-XXXXXXXX”、”XXX-XXXXXXX”、”XXX-XXXXXXXX”、”XXXXXXX”和”XXXXXXXX):^(\(\d{3,4}-)|\d{3.4}-)?\d{7,8}$
6 国内电话号码(0511-4405222、021-87888822):\d{3}-\d{8}|\d{4}-\d{7}
7 身份证号(15位、18位数字):^\d{15}|\d{18}$
8 短身份证号码(数字、字母x结尾):^([0-9]){7,18}(x|X)?$ 或 ^\d{8,18}|[0-9x]{8,18}|[0-9X]{8,18}?$
9 帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
10 密码(以字母开头,长度在6~18之间,只能包含字母、数字和函数时去掉去掉那个反斜杠,一般的错误都在这里
25 xml文件:^([a-zA-Z]+-?)+[a-zA-Z0-9]+\\.[x|X][m|M][l|L]$
26 中文字符的正则表达式:[\u4e00-\u9fa5]
27 双字节字符:[^\x00-\xff] (包括汉字在内,可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1))
28 空白行的正则表达式:\n\s*\r (可以用来删除空白行)
29 HTML标记的正则表达式:<(\S*?)[^>]*>.*?</\1>|<.*? /> (网上流传的版本太糟糕,上面这个也仅仅能部分,对于复杂的嵌套标记依旧无能为力)
30 首尾空白字符的正则表达式:^\s*|\s*$或(^\s*)|(\s*$) (可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式)
31 腾讯QQ号:[1-9][0-9]{4,} (腾讯QQ号从10000开始)
32 中国邮政编码:[1-9]\d{5}(?!\d) (中国邮政编码为6位数字)
33 IP地址:\d+\.\d+\.\d+\.\d+ (提取IP地址时有用)
PHP正则表达式处理函数
1. int preg_match ( string pattern, string subject [, array matches [, int flags]] )
用法:
1)在 subject 字符串中搜索与 pattern 给出的正则表达式相匹配的内容。
2)如果提供了 matches,则其会被搜索的结果所填充。$matches[0] 将包含与整个模式匹配的文本,$matches[1] 将包含与第一个捕获的括号中的子模式所匹配的文本,以此类推。
3)flags 参数自 PHP 4.3.0 起可用,flags 可以是下列标记: PREG_OFFSET_CAPTURE
如果设定本标记,对每个出现的匹配结果也同时返回其附属的字符串偏移量。注意这改变了返回的数组的值,使其中的每个单元也是一个数组,其中第一项为匹配字符串,第二项为其偏移量。
例如下面的例子,匹配一个URL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
|
2. int preg_match_all ( string pattern, string subject [, array matches [, int flags]] )
与 preg_match_all 用法完全一致,不过它匹配的是所有的信息。
例如下面的例子,匹配的是所有符合正则表达式的内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
这是一个正则表http://www.baidu1.com达式的匹配函数
这是一个正则表https://mail.baidu2.com达式的匹配函数
这是一个正则表https://news.baidu3.com达式的匹配函数
这是一个正则表https://www.baidu4.org达式的匹配函数
这是一个正则表https://www.baidu5.net达式的匹配函数
这是一个正则表ftps://www.baidu6.com达式的匹配函数
这是一个正则表ftp://www.google7.com达式的匹配函数
函数
;
;
{
;
;
;
;
;
{
;
}
|
上面的输出结果 $arr 的结果没有将一次次匹配的结果分开,也就是所有的子模式都写入一个数组中,没有将结果分成单独的一个数组。
结果中 第零个数组包含了所有的全模式,第一个数组包含了所有的第一个子模式。
可以通过修改上面的代码,实现结果的分开显示。
在上面的 preg_match_all 方法中,第四个参数传入 PREG_SET_ORDER,即可实现每一个全模式和子模式的分开展示。
其实,默认模式的参数即为 PREG_PATTERN_ORDER,传入该参数即相当于不传入参数。
3.mixed preg_replace(mixed pattern,mixed replacement,mixed subject [,int limit])
替换函数,pattern是正则表达式,replacement是替换成的内容,也就是把匹配到符合正则表达式的内容替换为 replacement,subject是查找的字符串,即替换的是这个字符串里面的内容。
执行该程序就会将str字符串中的字母替换为空。
另外,可以指定替换的次数,也就是第四个参数
这样,就可以实现只替换三次。
另外,可以实现多对多数组的替换,这是一个比较常用的方法,例如
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
;
;
(
,
,
,
,
,
'/\[align=(.*?)\](.*?)\[\/align\]/'
;
(
,
,
,
,
,
;
;
|
上面就可以实现中括号标签转化为HTML标签。
好,关于正则表达式函数,掌握这三个就基本够用了,其他的还有正则表达式分割函数,直接用PHP里面的字符串分割即可,不在此叙述了。
本篇总结
本篇介绍了正则表达式的相关语法以及在PHP中的正则表达式匹配函数,以上所有便是PHP正则表达式的相关内容,希望对大家有帮助~
请发表评论