PHP 正则表达式的使用

正则表达式:是一种描述字符串结构的语法规则,是一个特定的格式化模式,可以匹配、替换、截取匹配的字符串。好比计算机中的文件查找(*.text)会罗列出所有的后缀为.text的文件。

正则表达式术语:grep、egrep、POSIX、Perl、PCRE。

正则表达式的语法规则:一个完整的正则表达式有两部分组成,元字符和文本字符。元字符就是具有特殊含义的字符,如前面的(*)和(?)。文本字符就是普通的文本,如字母和数字等。PCRE风格的正则表达式一般都放置在定界符(/)中间。如(/\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/)、(/^http:\/\/(www\.)?.+.?$/)。


一、行定位符(^和$)

行定位符就是用来描述字符串的边界。(^)表示行的开始;($)表示行的结尾。

字符串:$str1 = tm equal Tomorrow Moon html utmost

字符串:$str2 = Tomorrow Moon equal tm html utmost

正则表达式:^tm

结果:字符串str1和正则表达式匹配,str2就不匹配了。

正则表达式改为:tm$

结果:字符串str2和正则表达式匹配,str1就不匹配了。

如果需要查找到匹配字符在字符串的任意位置

正则表达式:tm

结果:str1和str2和正则表达式都匹配。


二、单词定界符(\b and \B)

单词定界符:表示要查找的字符串为一个完整的单词。

字符串:$str1 = Tomorrow Moon html utmost

字符串:$str2 = Tomorrow Moon html utmost

正则表达式:\btm\b

结果:没有匹配正则表达式的结果。(查询完整的单词)

正则表达式:\Btm\B

结果:html和utmost就匹配。(查询不能是完整的单词)


三、字符类([])

正则表达式时是区分大小写的,如果要忽略大小写看就要使用([]),但是([])只能匹配一个字符,如tm就要写成:[Tt][Mm]。

预定义字符类

POSIX预定义字符串
预定义字符类 说明
[:digit:] 十进制数字集合。等同于[0-9]
[[:alnum:]] 字母和数字的集合。等同于[a-zA-Z0-9]
[[:alpha:]] 字母集合。[a-zA-Z]
[[:blank:]] 空格和制表符
[[:xdigit:]] 十六进制数字
[[:punct:]] 特殊字符集合。包括键盘上所有特殊字符,如!@#$等
[[:print:]] 所有的可打印字符(包括空白字符)
[[:space:]] 空白字符(包括空格、换行符、换页符、回车符、水平制表符)
[[:graph:]] 所有的可打印字符(不包括空白字符)
[[:upper:]] 所有的大写字母,[A-Z]
[[:lower:]] 所有的小写字母,[a-z]
[[:cntrl:]] 控制字符
  PCRE的预定字符类则是使用反斜线来表示的


四、选择字符(|)

选择字符可以理解为“或”。[Tt][Mm] 等价于 (T|t)(M|m) 。

使用 [] 和 | 的区别在于 [] 只能匹配单个字符,而 | 可以匹配任意长度的字符串。TM|tm|Tm|tM 和上述的正则是等价的。


五、连字符(-)

变量命名规则是只能以字母和下划线开头。例如要匹配第一个字母,就要写成 [a,b,c,d...A,B,C,D...],这样写会很麻烦,而且语句会很长,不易读。连字符来解决这个问题。连字符

可以表示为字符的范围。字母可能表示为:[a-zA-Z]


六、排除字符([^])

排除字符表示排除不满足的字符

[^a-zA-Z_]

表示:不以字母开头和下划线的变量名


七、限定符(?*+{n,m})

限定符表示:对于重复出现字母或字符串,可以使用限定符去匹配。

限定符说明举例
匹配前面的字符零次或一次colou?r,该表达式可以匹配colour和color
+匹配前面的字符一次或多次go+gle,该表达式可以匹配的范围从gogle到goo...gle
*匹配前面的字符零次或多次go*gle,该表达式可以匹配的范围从ggle到goo...gle
{n}匹配前面的字符n次go{2}gle,该表达式可以匹配的范围从google
{n,}匹配前面的字符最少n次go{2,}gle,该表达式可以匹配的范围从google到goo...gle
{n,m}匹配前面的字符最少n次,最多m次employe(0,2),该表达式可以匹配employ、employe和employee三种情况

八、点号字符(.)

点字符(.)可以匹配除换行符外的任意一个字符。

例子:匹配以s开头、t结尾、中间包含一个字母的单词。

格式:^s.t$

匹配的单词可以有:sat、set、sit等等。

例如:第一个字母是r,第三个字母是s。最后一个字母是t

格式:^r.s.t$


九、转义字符(\)

正则表达式中的转义字符(\)和PHP中的大同小异,都是将特殊字符(如“,”、“?”、“\”等)变为普通字符。

例如:255.255.255.255 这样格式的IP地址。

错误格式:[0-9]{1,3}(.[0-9]{1,3}){3}

正确的格式:[0-9]{1,3}(\.[0-9]{1,3}){3}


反斜线不单单做转义字符,还有其他一些功能。

反斜线可以将一些不可打印的字符显示出来

字符说明
\a警报,即ASCII中的<BEL>字符(0x07)
\b退格,即ASCII中的<BS>字符(0x08)。在PHP中只有在([])里面使用才表示退格
\eEscape,即ASCII中的<ESC>字符(0x1B)
\f换页符,即ASCII中的<FF>字符(0x0C)
\n换行符,即ASCII中的<LF>字符(0x0A)
\r回车符,即ASCII中的<CR>字符(0x0D)
\t水平制表符,即ASCII中的<HI>字符(0x09)
\xhh十六进制代码
\ddd八进制代码
\cx即control-x的缩写,匹配由x指明的控制字符,其中x是任意字符

还可以指定预定义字符集

反斜线指定的预定义字符集
预定义字符集说明
\d任意一个十进制数字,相当于[0-9]
\D任意一个非十进制数字
\s任意一个空白字符(空格、换行符、换页符、回车符、水平制表符),相当于[\f\n\r\t]
\S任意一个非空白字符
\w任意一个单词字符,相当于[a-zA-Z0-9]
\W任意一个非单词字符

反斜线还有定义断言功能

反斜线定义断言的限定符
限定符说明
\b单词分界符,用来匹配字符串中的某些位置,\b是以统一的分解符来匹配
\B非单词分解符序列
\A总是能够匹配待搜索文本的起始位置
\Z表示在未指定任何模式下匹配的字符,通常是字符串的末尾位置,或者是在字符串末尾的换行符之前的位置
\z只匹配字符串的末尾,而不考虑任何换行符
\G当前匹配的起始位置


十、括号字符(())

小括号字符的第一个作用就是可以改变限定字符的作用范围,如“|”、“*”、“^”等。

(thir|four)th

这个表达式的意思是匹配单词thirth或fourth,如果不用小括号,那么就变成了匹配单词thir和fourth。

小括号的第二个作用就是分组,就是子表达式。

(\.[0-9]{1,3}){3}

就是对分组 (\.[0-9]{1,3}) 进行重复操作3次。


十一、反向引用

反向引用:就是依靠子表达式的“记忆”功能来匹配连续出现的字符串或字母。

如匹配连续两个it。

格式:(it)\1

如果要匹配的字符串不固定,那么括号内的字符串写成正则表达式,也可以使用多个分组,顺序是从左到右。

([a-z])([A-Z])\1\2

除了用数字表示分组外,还可以自己来指定分组名称。

(?P<subname>...)

反向引用该分组

(?P=subname)

上面的表达式就修改成

(?P<fir>[a-z])(?P<sec>[A-Z])(?P=fir)(?P=sec)


十二、模式修饰符

模式修饰符的作用是设定模式。也就是规定正则表达式英爱如何解释和引用。不同的语言都有不同的模式设置,PHP中主要模式是

模式修饰符
修饰符表达式写法说明
i(?i)...(?-i)、(?i:...)忽略大小写模式
M(?m)...(?-m)、(?m:...)多文本模式。即字符串内部有多个换行符时,影响"^"和"$"的匹配
s(?s)...(?-s)、(?s:...)单文本模式。在此模式下,元字符点号(.)可以匹配换行符。其他模式则不能匹配换行符
X(?x)...(?-x)、(?x:...)忽略空白字符

模式修饰符既可以写在正则表达式的外面,也可以写在表达式内。如忽略大小写模式,可以写为 /tm/i、(?i)tm(?-i)、(?i:tm) 三种格式


十三、POSIX扩展正则表达式函数

1.ereg()函数和eregi()函数的使用

格式:bool ereg/eregi(string pattern, string string, [array regs])

说明:在字符串string中匹配表达式pattern,如果匹配成功返回true,否则返回false。如果有第三个参数regs,则将成功匹配的字符串按子表达式划分,并存储到regs数组中。

注意:ereg区分大小写,eregi不区分大小写。

<?php
    $ereg = '^[$][[:alpha:]_][[:alnum:]]*';
    ereg($ereg, '$_name', $register);
    var_dump($rehister);
?>
结果显示:
array(1){[0]=>string(6)"$_name"}


2. ereg_replace()函数和eregi_replace()函数

格式:string ereg_replace/eregi_replace(string pattern, string replacement, string string)

说明:在字符串string中匹配表达式pattern。如果匹配成功,则使用replacement来替换匹配字符串,并返回替换后的string。

注意:ereg_replace()函数区分大小写,eregi_replace()函数不区分大小写。

<?php
	$ereg = ‘tm’;
	$str = ‘hello,tm,Tm,tM,TM’;
	$rep_str = eregi_replace($ereg, ’TM’, $str)
	echo $rep_str;
?>
显示结果:
hello,TM,TM,TM,TM

3. split()函数和spliti()函数

格式:array split/spliti(string pattern, string string, [int limit])
说明:使用表达式pattern来分割字符串string。如果有参数limit,那么数组最多有limit个元素,剩余部分都写到最后一个数组元素中。如果函数错误,则返回false。
注意:split()函数区分大小写,spliti()函数不区分大小写。

<?php
	$ereg = ‘is’;
	$str = ‘this is a register book’;
	$arr_str = spliti($ereg,  $str)
	car_dump($arr_str);
?>
显示结果:
array(4){[0=>string(2)”Th”[1]=>string(1)””[2]=>string(6)”a reg”][3]=>string(9)”ter book”}

十四、PCRE兼容正则表达式函数

1.preg_grep()函数

格式:array preg_grep(string pattern, array input)

说明:使用数组input中的元素一一匹配表达式pattern,最后返回由所有相匹配的元素所组成的数组。

<?php
	$preg = ‘/\d{3,4}-?\d{7,8}/’;
	$arr = array(’043212345678’,’0431-7654321’,’12345678’);
	$preg_arr = preg_grep($preg, $arr);
	var_dump($preg_arr);
?>
显示结果:
array(2){[0]=>string(12)”043212345678”[1]=>string(12)”0431-7654321”}

2. preg_match()函数和preg_match_all()函数

格式:int preg_match/preg_match_all(string pattern, string subject, [array matches])
说明:在字符串subject中匹配表达式pattern。函数返回匹配次数。如果有数组matches,那么每次匹配的结果都将存储到数组中。

注意:preg_match()的返回值是0和1,因为在该函数在匹配成功过后就停止继续查找了。而preg_match_all()函数则会一直匹配到最后才会停止。array matches参数对preg_match_all()函数是必须有的,而对preg_match()函数可以省略。

<?php
	$str = ’This is an example’;
	$preg = ‘/\b\w(2)\b/’;
	$num1 = preg_match($preg, $str, $str1);
	echo $num1.”<br>”;
	var_dump($str1);
	$num2 = preg_match_all($preg, $str, $str2);
	echo ‘<p>’.$num2.”<br>”;
	var_dump($str2);
?>
显示结果:
1
array(1){[0]=>string(2)”is”}
2
array(1){[0]=>array(2){[0]=>string(2)”is”[0]=>string(2)”is”}}

3. perg_quote()函数

格式:string preg_quote(string str, [string delimiter])

说明:该函数将字符串str中的所有特殊字符进行自动转义。如果有参数delimiter,那么该参数所包含的字符串有人将被转义。函数返回转义后的字符串。

<?php
	$str = ‘!、$、^、*、+、.、[、]、\\、/、b、<、>’
	$str2 = ‘b’;
	$match_one = perg_quote($str, $str2);
	echo $match_one;
?>
函数说明:
\t、\$、\^\*、\+、\.、\[、\]、\\、\/、\b、\<、\>
注意:这里的特殊字符是指正则表达式中具有一定意义的元字符。如“@”、"#"等则不会被当做特殊处理


4. perg_replace()函数

格式:mixed perg_replace(mixed pattern, mixed replacement, mixed subject, [int limit])

说明:在字符串subject中匹配表达式pattern,并将匹配项替换成字符串replacement。如果有参数limit,则就替换limit次

注意:如果参数中调用的是数组,有可能在调用过程中并不是按照数组的key值进行替换,所以在调用之前需要将数组重新排列ksort()。

<?php
          $string = '[b]粗体字[/b]';
          $b_rst = preg_replace('/\[b\](.*)\[\/b\]/i','<b>$1</b>',$string);
          echo $$b_rst;
?>
显示结果:
粗体字

preg_replace()函数中的字符串“$1”是正则表达式外调用分组,按照$1、$2排列,顺序是从左到有的分组顺序,$0表示的时整个正则表达式的匹配值。


5. preg_replace_callback()函数

格式:mixed preg_replace_callback(mixed pattern, callback callback, mixed subject, [int limit])

说明:preg_replace_callback()函数和 preg_replace()函数的功能相同,都用于查找替换字符串。不同的是 preg_replace_callback()函数使用一个回调函数(callback)来替换replacement参数。

注意: preg_replace_callback()函数中字符串使用““”引号,这样可以保证特殊字符号不被转义。

<?php
	function c_back($str) {
		$str = “<font color=$str[1]>$str[2]</font>”;
		return $str;
	}
	$string = ‘[color=blue]字体颜色[/color]’;
	echo preg_replace_callback(‘/\[color=(*)\](.*)\[\/color\]/U’,”c_back”, $string); 
?>
结果显示:
字体颜色


6. preg_split()函数

格式:array preg_split(string pattern, string subject, [int limit])

说明:使用表达式pattern来分割字符串subject。如果有参数limit,那么数组最多有limit个元素。和ereg_split()函数使用方法相同。


十个常用的PHP正则语句

1.验证电子邮件

这是一个用于验证电子邮件的正则表达式,但这不是最高效,最完美的方法。

$email = "test@ansoncheung.tk";
if (preg_match('/^[^0-9][a-zA-Z0-9_]+([.][a-zA-Z0-9_]+)*[@][a-zA-Z0-9_]+([.][a-zA-Z0-9_]+)*[.][a-zA-Z]{2,4}$/',$email)) {
    echo "Your email is ok.";
} else {
    echo "Wrong email address format";
}

为了更加有效的验证电子邮件地址,推荐使用filer_var
if (filter_var('test+email@ansoncheung', FILTER_VALIDATE_EMAIL)) {
    echo "Your email is ok.";
} else {
    echo "Wrong email address format.";
}

2. 验证用户名 

这是一个用于验证用户名的实例,其中包括字母、数字(A-Z,a-z,0-9)、下划线以及最低5个字符,最大20个字符。同时,也可以根据需要,对最小值和最大值做合理的修改。

$username = "user_name12";
if (preg_match('/^[a-z\d_]{5,20}$/i', $username)) {
    echo "Your username is ok.";
} else {
    echo "Wrong username format.";
}

3. 验证电话号码 

这是一个验证美国电话号码的实例。

$phone = "(021)423-2323";
if (preg_match('/\(?\d{3}\)?[-\s.]?\d{3}[-\s.]\d{4}/x', $phone)) {
    echo "Your phone number is ok.";
} else {
    echo "Wrong phone number.";
}

4. 验证IP地址 

这是一个用来验证IPv4地址的实例。

$IP = "198.168.1.78";
if (preg_match('/^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/',$IP)) {
    echo "Your IP address is ok.";
} else {
    echo "Wrong IP address.";
}

5. 验证邮政编码 

这是一个用来验证邮政编码的实例。

$zipcode = "12345-5434";
if (preg_match("/^([0-9]{5})(-[0-9]{4})?$/i",$zipcode)) {
    echo "Your Zip code is ok.";
} else {
    echo "Wrong Zip code.";
}

6. 验证SSN(社会保险号) 

这是一个验证美国SSN的实例。

$ssn = "333-23-2329";
if (preg_match('/^[\d]{3}-[\d]{2}-[\d]{4}$/',$ssn)) {
    echo "Your SSN is ok.";
} else {
    echo "Wrong SSN.";
}

7. 验证信用卡号

$cc = "378282246310005";
if (preg_match('/^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6011[0-9]{12}|3(?:0[0-5]|[68][0-9])[0-9]{11}|3[47][0-9]{13})$/', $cc)) {
    echo "Your credit card number is ok.";
} else {
    echo "Wrong credit card number.";
}

8. 验证域名

$url = "http://ansoncheung.tk/";
if (preg_match('/^(http|https|ftp):\/\/([A-Z0-9][A-Z0-9_-]*(?:\.[A-Z0-9][A-Z0-9_-]*)+):?(\d+)?\/?/i', $url)) {
    echo "Your url is ok.";
} else {
    echo "Wrong url.";
}

9. 从特定URL中提取域名

$url = "http://ansoncheung.tk/articles";
preg_match('@^(?:http://)?([^/]+)@i', $url, $matches);
$host = $matches[1];

echo $host;

10. 将文中关键词高亮显示

$text = "Sample sentence from AnsonCheung.tk, regular expression has become popular in web programming. Now we learn regex. According to wikipedia, Regular expressions (abbreviated as regex or regexp, with plural forms regexes, regexps, or regexen) are written in a formal language that can be interpreted by a regular expression processor";

$text = preg_replace("/\b(regex)\b/i", '<span style="background:#5fc9f6">\1</span>', $text);

echo $text;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值