您的位置:首页 > 编程语言 > PHP开发

浅谈正则表达式-PHP为例

2015-06-12 18:26 573 查看
第一次比较系统的学习正则表达式,本篇文章以PHP语言为例来学习。

基本概念

  正则表达式=普通字符(如a-z)+分隔符(正斜线(/)、hash符号(#) 以及取反符号(~))+特殊字符(称为元字符) 两者的组合;

PHP的正则有两种:POSIX和PERL(PCRE Perl Compatible Regular Expression),后者PHP支持得更好

匹配原理

  简单描述下,通常是由字符串位置0开始尝试匹配,若匹配成功存储这个子串;若在某一个位置匹配失败则后移一个位置,从位置1开始重新匹配。直到匹配成功或者匹配到最后一个位置都没有找到成功的子串。

匹配模式

  看名字,是不是想到了设计模式中的单例模式了呢?

贪婪模式

    在可匹配与可不匹配的时候,优先匹配,比如量词用*或+

  2. 懒惰模式

    在可匹配与可不匹配的时候,优先不匹配,比如量词用?。 *? 在正则中代表非贪婪匹配模式,会尽量少的匹配字符,如果不加 ?就是贪婪模式,此时通配符会把所有字符都匹配掉

用途

查找:检查一个串是否包含某个子串,而子串是符合正则表达式条件的子串,最后得到所有符合条件的子串集合

替换:将上一条查找出来的子串替换成特定的字符串

正则分隔符

字符说明备注
/表达式/一个完整的正则表达式的边界若表达式内有/,需要用转义字符\转义 $p="/ab\//"
#表达式#一个完整的正则表达式的边界2若表达式内有#,需要用转义字符\转义 $p="#ab/\##"
~表达式~一个完整的正则表达式的边界3若表达式内有~,需要用转义字符\转义 $p="~ab/#\~~"
|表达式|一个完整的正则表达式的边界4若表达式内有|,需要用转义字符\转义 $p="|ab/#\~\||"

元字符

边界定位符

字符说明备注
^开头, 用于子字符串的末尾,,表示子字符串必须出现在字符串的开头见代码示例1
$结尾用于子字符串的末尾,,表示子字符串必须出现在字符串的末尾,可以和^搭配使用
\b匹配一个单词边界,匹配单词和空格之间的位置
\B匹配一个非单词边界,匹配单词和空格之间的位置

量词元字符

字符说明(都是返回能得到的最长子串)备注
*0次或多次匹配前面的子表达式,等价于{0,}
0次或1次匹配前面的子表达式等价于{0,1}懒惰模式就用这个
+1次或多次匹配前面的子表达式等价于{1,}
{n}n次匹配前面的子表达式
{n,}大于等于n次匹配前面的子表达式
{,n}小于等于n次匹配前面的自表达式
{n,m}最少n次,最大m次,匹配前面的自表达式

普通元字符

字符 说明备注
\d数字,等价于[0-9]
\D非数字,等价于[^0-9]
\w匹配字母、数字、下划线,等价于[a-zA-z0-9_]
\W匹配非[^a-zA-z0-9_]
\s匹配任何空白字符(包括空格、制表符、换页符),等价于[\n\f\t\r\v]
\S匹配任何非空白字符(包括空格、制表符、换页符),等价于[^\n\f\t\r\v]
\转义字符
.匹配除换行符(\n)之外的任何字符当一个字符类的开始或末尾处使用点号时,只能成为普通的点号字符

[]只能匹配一个字符,自带“或”的属性,后面可以跟修饰符。

方括号内,个别字符有不同的含义:

  ^仅在作为第一个字符(方括号内)时,表明字符类取反

  - 标记字符范围

  \ 转义字符

()包含一个子表达式,要表达“或”需要“|”
|开始一个可选分支

分组元字符

字符说明备注
()将表达式括起来,与其他元字符配合使用

引用

字符说明备注
&在替换字符串中,符号&代表整个正则表达式所匹配的字符串的内容仅在替换时使用
\n(n=1,2...)转移数字\n代表索索字符串的第n个括号中正则表达式所匹配的字符串内容 查找、替换都能使用

各元字符的优先级

优先级字符集说明
1\转义
2^\w\d等
3(),[]
4*,+,?,{}两次
5^,$断言,位置
6|分组

PHP中正则相关的几个方法

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

用途:返回值是匹配成功的次数0或者1,在匹配到1次以后就会停止搜索

参数:$pattern 为正则表达式;$subject为被搜索的字符串;$matches可选,存储匹配结果的数组,$matches[0]包含整个模式匹配的文本,$matches[1]为第一个括号中的子模式所匹配的文本,依次类推

代码示例:

$subject = "abcdef";
$pattern = '/a(.*)(\w)d/';
preg_match($pattern, $subject, $matches);
print_r($matches);


 返回结果:

  Array
  (
    [0] => abcd
    [1] => b
    [2] => c
  )  

2.preg_match_all($pattern, $subject, $matches,$flags]);

 用途:循环获取一个列表的匹配结果数组。

 参数:$pattern 为正则表达式;$subject为被搜索的字符串;

    $matches必选,存储匹配结果的多维数组

   $flags有多个值,int类型。

      case: flag=1,PREG_PARTTERN_ORDER 默认值,$matches[0]存储的是全部模式匹配的数组,$matches[1]为第一个括号中的子模式所匹配的文本array,依次类推。

$p = "|<[^>]+>(.*?)</[^>]+>|i";
$str = "<b>example: </b><div align=left>this is a test</div>";
preg_match_all($p, $str, $matches,1);
print_r($matches);


运行结果:

Array
(
[0] => Array
(
[0] => <br>example: </br>
[1] =><div>this is a test</div>

)
[1] => Array
(
[0] => example:
[1] => this is a test
)
)  

      case: flag=2,PREG_SET_ORDER ,$matches[0]存储的是第一括号里面模式匹配的所有数组,$matches[1]为第而括号里面模式匹配的所有数组,依次类推。

   代码示例: 

$p = "|<[^>]+>(.*?)</[^>]+>|i";
$str = "<b>example: </b><div align=left>this is a test</div>";
preg_match_all($p, $str, $matches,2);
print_r($matches);


 运行结果:

Array
(
[0] => Array
(
[0] => <br>example: </br>
[1] => example:
)

[1] => Array
(
[0] =><div>this is a test</div>

[1] => this is a test
)

)

3.preg_replace($pattern, $replacement, $string); 

用途:找到一个字符串匹配的子串,并交换子串之间的位置。

参数:第一个参数表示正则表达式;第二个参数表示新的位置,$1 表示所以父正则表达式list的每个元素的第一个子元素;第三个参数表示源字符串。

返回:$string

$string = 'April 15, 2014;July 16, 2015';
$pattern = '/(\w+) (\d+), (\d+)/i';
$replacement = '$3, ${1} $2';
preg_match_all($pattern,$string,$matches,2);
print_r($matches);
echo preg_replace($pattern, $replacement, $string);


结果:

Array
(
[0] => Array
(
[0] => April 15, 2014
[1] => April
[2] => 15
[3] => 2014
)

[1] => Array
(
[0] => July 16, 2015
[1] => July
[2] => 16
[3] => 2015
)

)
2014, April 15;2015, July 16


常用示例

1.匹配邮箱:

'/^[a-zA-z_\-.]+@[a-zA-z_\-.]+\.[a-zA-z_\-.]+$/'

或 '/^[\w\-.]+@[\w\-.]+\.[\w\-.]+$/'

tips:在中括号末尾的的. 是不需要转移字符的,而在中括号外的.就一定要记得加上转义

2. ^$间隔符加深理解:

$str="abcdae";
$p1='/^ab/';
$p2='/^a$/';
echo preg_match($p1,$str);//1
echo preg_match($p2,$str);//0


3.常用的一个注册页面的验证

 

$user = array(
'name' => 'spark1985',
'email' => 'spark@imooc.com',
'mobile' => '13312345678'
);
//进行一般性验证
if (empty($user)) {
die('用户信息不能为空');
}
if (strlen($user['name']) < 6) {
die('用户名长度最少为6位');
}
//用户名必须为字母、数字与下划线
if (!preg_match('/^\w+$/i', $user['name'])) {
die('用户名不合法');
}
//验证邮箱格式是否正确
if (!preg_match('/^[\w\.]+@\w+\.\w+$/i', $user['email'])) {
die('邮箱不合法');
}
//手机号必须为11位数字,且为1开头
if (!preg_match('/^1\d{10}$/i', $user['mobile'])) {
die('手机号不合法');
}
echo '用户信息验证成功';


RegisterPage
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: