第一次比较系统的学习正则表达式,本篇文章以PHP语言为例来学习。

基本概念

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

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

匹配原理

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

匹配模式

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

  1. 贪婪模式

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

  2. 懒惰模式

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

用途

  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]  digit
 \D  非数字,等价于[^0-9]  
 \w  匹配字母、数字、下划线,等价于[a-zA-z0-9_]  word
\W  匹配非[^a-zA-z0-9_]  
\s  匹配任何空白字符(包括空格、制表符、换页符),等价于[\n\f\t\r\v]  space
\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

最新文章

  1. 各种Js封装
  2. js框架设计1.2对象扩展笔记
  3. Canvas里绘制矩阵文字
  4. Linux使用ssh公钥实现免密码登录Linux
  5. Linux sar分析网卡流量
  6. magento提速的一些小技巧,列举manegnto网站提速的
  7. Azure Backup 入门
  8. 从零基础入门JavaScript(2)
  9. windows driver inf文件
  10. Android设备定制为永不锁屏
  11. 百度地图坐标转换API和地图API
  12. java--多线程之Runnable
  13. Google大数据三篇著名论文----中文版
  14. PHP获取图片颜色值
  15. 《安卓网络编程》之第五篇 WebView的使用
  16. iOS-FMDB事务【批量更新数据】
  17. JQGrid导出Excel文件
  18. Android中自定义广播的实现
  19. 【EF6学习笔记】(八)更新关联数据
  20. 《React Native 精解与实战》书籍连载「React Native 底层原理」

热门文章

  1. SDK location not found. Define location with sdk.dir in the local.properties file or with an ANDROID
  2. com.squareup.okhttp.Interceptor
  3. Unity插件
  4. python与execl的读写
  5. hp raid json
  6. pin
  7. lowercase calligraphic letters
  8. 我与0xc000007b奋斗的日子
  9. 实用JS系列——面向对象中的类和继承
  10. HTTPS和HTTP的区别: