正则表达式实例解析

类别: 技术

时间:2016-06-02 10:14:14

字数:6253

版权所有,未经允许,请勿转载,谢谢合作~

### 前言

正则表达式(regular expression)几乎在所有主流计算机语言中都有涉及,初学者很多时候都是从某些地方copy过来,如果不了解它,那也不知道copy的东西对不对。

它并不是一门语言,而是对字符串操作的一种逻辑公式,常常用regex表示。有趣的是,正则表达式并非计算机首创,而是源于数学科学家Stephen Kleene的《神经网事件的表示法》论文中, 再被引入Unix工具软件,自此广泛被利用,验证了理论先于实践。虽然不同的语言上会有一些流派的小差异,思想却是相同,为了方便表述,本处多以JavaScript为例。

正则就像翻译一样,同样的意思,有不同的翻译法,不同的高度。

PS:讲个小故事,有人以为只要英语足够牛逼,就可以成为牛逼的翻译官,too young too simple。电影《降临》七肢桶提供表意“武器”,这个可以翻译成知识,也可以成兵器,差别极大。比起外语能力,更重要的是知识深度与良知正义,所以翻译官就像语言学家一样,永无止境的东西。

正则表达式无非是实现两个功能,搜索与替换。博客内容来自[西法](http://www.boatsky.com "太空船博客" rel="nofollow")之前写的静态页,附带表达式工具:https://www.boatsky.com/static/tools/regexp/regexp.html

### 常用语法

^字符串开始位置

$字符串结束位置

\转义字符

\d数字

\D非数字

\w任何单词字符,包括字母数字下划线

\W非单词字符

\s不可见字符

\S可见字符

+匹配表达式1次以上

星号,匹配表达式任意次,尽量使用*?这种非贪婪的模式

?匹配表达式1次或0次

{n}匹配表达式n次,n非负

{n,m}匹配表达式n次至m次,n<=m

[abcde]匹配字符集任意一个,等价于[a-e]

[^0-9]匹配不在本字符集任意一个,等价于\D

(x|y|z)匹配字符集任意一个,等价于[xyz]

\b 单词边界

\B 非单词边界

以下为非获取匹配子表达式

(?:pattern) 匹配pattern但不获取匹配结果,不进行存储供以后使用

(?=pattern) 正向肯定预查

(?!pattern) 正向否定预查

(?<=pattern) 反向肯定预查

(?

### 简单实例

#### QQ号

分析:QQ号是纯数字,4位至10位,不过也有把11位手机号当QQ的情况

正则:

```

/^[1-9]\d{3,10}$/

```

#### 手机号码

分析:

移动号19:134,135,136,137,138,139,147,150,151,152,157,158,159,178,182,183,184,187,188

联通号09:130,131,132,155,156,185,186,145,170,171,176

电信号06:133,153,177,180,181,189

综合:

130,131,132,133,134,135,136,137,138,139

145,147

150,151,152,153,155,156,157,158,159

170,171,176,177,178

180,181,182,183,184,185,186,187,188,189

正则:

```

/^(13|14|15|17|18)[0-9]{9}$/

```

#### 数字

js中,如果想验证整数n,可以直接用Number.isInteger(n)。

如果要验证n是否是数字,我们一般是使用:

Object.prototype.toString.call(n) === '[object Number]'

这存在几个明显的问题:

其一:如果n是一个数字,传输中是以String来传的,这时有问题

其二:如果n为NaN,也认为是数字,这可能不是我们想要的

其三:JS数字范围有限,如果超过了JS数字的范围1.797693134862316e+308,n变成了Infinity,这时上式也成立,我们并不想认为Infinity是数字。

其四:我们可能只想要一个验证长是不是数字,比如有个极大的数,超出了JS数的范围,不应该认为这个极大的数就不是数,只是原生JS不支持而已。

为了解决这些问题,用正则匹配。

我们把数分成整数、小数、指数,其中整数部分与指数数字是带正负的

整数 [\+\-]?\d*

小数部分 \.\d+

指数 e[\+\-]?\d*

最终

```

/^[\+\-]?\d*(\.\d+)?(e[\+\-]?\d*)?$/

```

#### 邮箱

分析:邮箱的格式一直是一个有争议的问题,最常见的格式如xx@xx.xx,不过像xx.oo@xx.com.cn,xx_xx-xx+xx.xx@xx-xx.xx也能见到。

不过多数邮箱还是会在做出类似以下的限定:

1.邮箱只能包含字母数字.-_+与一个@,@之前必须有字母或数字,@之后必须要"2级域名"."1级域名"

2.开头必须是字母或数字,不能有连续的.-_

3.一级域名一般是只包含字母

正则:

```

/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.[a-zA-Z]+$/

```

#### 网址

分析:网址正则几乎随处可见,前缀是传输协议,如http,https,ftp,sftp,rtsp(实时流传输协议),mms(串流媒体传送协议),magnet(BT种子)等等,接着则是三级域名(有可能省略),二级域名,一级域名,当然也可能只是IP址,最后详细路径

本处,以本网为例

正则:

```

/^http(s?):\/\/((\w)+\.)?boatsky\.com(\.cn)?(\/|$)/i

```

#### 日期时间

分析:日期时间格式 多样,为了便于表示,以传统日期年月日时分秒,格式xxxx/xx/xx xx:xx:xx为例,其中年份为4位数,所有位数不足都须补0

首先,我要要验证这个输入是否像一个日期,并不考虑这个日期是否存在

日期+时间格式正则:

```

/^\d{4}\/(0[1-9]|1[0-2])\/(0[1-9]|[12][0-9]|3[01])(\x20)(2[0-3]|[0-1][0-9]):([0-5]\d):[0-5]\d$/

```

分析:如果加上1,3,5,7,8,10,12月有31天,4,6,9,11有30天,2月有28天(假设都是平年)

平年月份的正则:

```

/02\/(0[1-9]|1[0-9]|2[0-8])|(0[469]|11)\/(0[1-9]|[12][0-9]|30)|(0[13578]|1[02])\/(0[1-9]|[12][0-9]|3[01])/

```

所以平年的正则:

```

/^\d{4}\/((02\/(0[1-9]|1[0-9]|2[0-8])|(0[469]|11)\/(0[1-9]|[12][0-9]|30)|(0[13578]|1[02])\/(0[1-9]|[12][0-9]|3[01])))(\x20)(2[0-3]|[0-1][0-9]):([0-5]\d):[0-5]\d$/

```

再加上闰年(能被4整除,若能被100整除则需要再被400整除,就是所谓的“4年一闰,100年不闰,400年再闰”),闰年2月29天,平年2月28天

闰年2月有29天也就是两种情况:

1.能被4整除且不能被100整除。什么样的数能被4整除?因为100能被4整除,所以只要保证后两位数能被4整除就行了,即“个位为048,十位为偶数”或“个位为26,十位为奇数”,加上个位与十位不能同时为0,如下:

```

/\d{2}([2468][048]|[13579][26]|0[48])/

```

2.能被400整除。千位与百位需要被4整除,(没有公元0年,只有公元前1年与公元1年)

```

/([2468][048]|[13579][26]|0[48])00/

```

所以闰年的正则:

```

/\d{2}([2468][048]|[13579][26]|0[48])|([2468][048]|[13579][26]|0[48])00/

```

综上,最终结果:

```

/^((\d{4}\/((02\/(0[1-9]|1[0-9]|2[0-8])|(0[469]|11)\/(0[1-9]|[12][0-9]|30)|(0[13578]|1[02])\/(0[1-9]|[12][0-9]|3[01]))))|((\d{2}([2468][048]|[13579][26]|0[48])|([2468][048]|[13579][26]|0[48])00)\/(02\/(0[1-9]|1[0-9]|2[0-9])|(0[469]|11)\/(0[1-9]|[12][0-9]|30)|(0[13578]|1[02])\/(0[1-9]|[12][0-9]|3[01]))))(\x20)(2[0-3]|[0-1][0-9]):([0-5]\d):[0-5]\d$/

```

#### 密码复杂度

分析:现在很多网站都流行对用户的密码进行安全等级评定,提醒用户设置更复杂的密码,更大可能的保护账户安全。

其实所谓的复杂度,无非就是用多个正则进行配置,匹配上越多的正则,则复杂度越高

本处对密码设以下规则,长度8-32,建议包括大写字母,建议包括小写字母,建议包括数字,建议包括特殊字符,不建议包括三个连续字符,

### JavaScript中简单使用

在JS中,正则表达式用RegExp对象表示,可以用RegExp(pattern,attributes)构造函数来创建RegExp对象,其第一个参数pattern是上述的正则表示式,第二个参数是修饰符,g(全局匹配),i(不区分大小写匹配),m(多行匹配)

```javascript

var regExp = new RegExp("/^(13|14|15|17|18)[0-9]{9}$/");

```

也可以特殊的直接量语法创建:

```javascript

var regExp = /^(13|14|15|17|18)[0-9]{9}$/;

```

RegExp包括以下方法:

complie:编译正则,增快速度

test:检索字符串指定值

```javascript

var regExp = new RegExp(/^(13|14|15|17|18)[0-9]{9}$/);

var result = regExp.test("18812345678"); //返回true或false,这里是true

```

exec:检索字符串指定值,并确定位置,如果搜索修饰符不是g,那么返回值第0个是匹配上的字符串还包括index(匹配文本第一个的位置)与input(当前被匹配的字符串)两个属性

```javascript

var regExp = new RegExp(regExpValuePattern);

var checkResult = regExp.exec(checkContentValue);

if(checkResult){

printResult = "位置:" + checkResult.index + ",字符:" + checkResult[0];

}

var regExp = new RegExp(/a/,g);

var result;

while((result == regExp.exec("abcdefabdaafg"))){

console.log(result);

console.log(regExp.lastIndex);

}

```

String对象有search,match,replace,split是支持正则表达式的

比如用replace把一个正整数转成千位用,分隔

```javascript

function numberFormat(num) {

if(!(Object.prototype.toString.call(1) === '[object Number]' && Math.floor(num) === num)){

return num;

}

let reg=/\d{1,3}(?=(\d{3})+$)/g;

return (num + '').replace(reg, '$&,');

}

```

### PHP中简单使用

如果懒的装PHP,则可以使用在线的PHP编译方式:

preg_match("$regex",$byMatchStr),其中$regex为正则表达式,$byMatchStr为被匹配的字符串,成功返回true,否则false:

```php

if(preg_match("/php/", "php is best language of the world. php is not pai huang pian.", $matches)){

echo "php was found:". $matches[0];

} else {

echo "php was not found:";

}

```

preg_match_all("$regex",$byMatchStr),其中$regex为正则表达式,$byMatchStr为被匹配的字符串,成功返回true,否则false:

```php

if(preg_match_all("/php/", "php is best language of the world. php is not pai huang pian.", $matches)){

echo "php was found:"

var_dump($matches); } else {

echo "php was not found:";

}

```

preg_replace("$regex",$str,$byMatchStr),其中$str把$byMatchStr替换掉的字符串:

```php

$byMatchStr = "php is best language of the world.";

echo $byMatchStr;

echo "\n";

echo preg_replace("/php/","JavaScript",$byMatchStr);

echo "\n";

echo $byMatchStr;

```

preg_split("$regex",$byMatchStr),使用正则转换数组:

```php

$byMatchStr = "php is best language of the world.";

$array = preg_split("/ /",$byMatchStr);

foreach($array as $a){

echo $a."\n";

}

```

preg_grep("$regex",$byMatchArray),使用正则替换数组,生成新数组:

```php

$byMatchArray = array("a","b","c","ab","ba","bc");

$newArray = preg_grep("/b$/",$byMatchArray);

var_dump($newArray);

```

全部留言

我要留言

内容:

网名:

邮箱:

个人网站:

发表

php正则表达式实例详解,正则表达式实例解析相关推荐

  1. python 自动化办公 案例_python自动化工具之pywinauto实例详解

    python自动化工具之pywinauto实例详解 来源:中文源码网 浏览: 次 日期:2019年11月5日 [下载文档: python自动化工具之pywinauto实例详解.txt ] (友情提示: ...

  2. pythonfor循环案例教程_python开发之for循环操作实例详解,pythonfor实例详解

    python开发之for循环操作实例详解,pythonfor实例详解 本文实例讲述了python开发之for循环操作.分享给大家供大家参考,具体如下: 下面是我做的一些学习记录供大家参考: #基本的f ...

  3. Windows XP系统下架设FTP服务器实例详解

    Windows XP系统下架设FTP服务器实例详解 [实例1]公司网络环境:ADSL + 路由器 + 交换机  + PC机,我们单位要在客户端架设FTP服务器,当然在服务器端也是可以的,主要用于内部资 ...

  4. java 自定义正则表达式_java中正则表达式实例详解

    Java中正则表达式运用实例(参看java中正则表达式运用详解): 测试代码 package test; /** * 在String的matches()方法,split()方法中使用正则表达式. * ...

  5. php正则实例,php 正则表达式实例详解(适合初学者)

    正则表达式实例详解(适合初学者) 数学公式正则表达式: (?'kh'()*([- ]){0,1}[0-9.] (?'-kh'))*([ -*/]{1}(?'kh'()*((?<=()([- ]) ...

  6. python 正则式替换_python 正则表达式参数替换实例详解

    正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配. Python 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式. re 模块使 Python ...

  7. oracle身份证的正则表达式,Oracle 正则表达式实例详解

    Oracle 正则表达式实例详解 FORM开发中的按行拆分需求:拆分后的行要有规律,并按前后层次排序 需求分析如下: 现有行: 2 , 2.1 , 2.2 , 2.3 3 2.1.1,2.1.2,2. ...

  8. oracle大对象实例_Oracle解析复杂json的方法实例详解

    问题背景: 当前在Oracle数据库(11G之前的版本)解析json没有可以直接使用的系统方法,网上流传的PLSQL脚本大多也只可以解析结构较单一的json串,对于结构复杂的json串还无法解析.如此 ...

  9. java技术详解_Java反射技术详解及实例解析

    前言 相信很多人都知道反射可以说是Java中最强大的技术了,它可以做的事情太多太多,很多优秀的开源框架都是通过反射完成的,比如最初的很多注解框架,后来因为java反射影响性能,所以被运行时注解APT替 ...

最新文章

  1. javaScript的DOM(一)
  2. 企业通信需要专业高效工具
  3. ocm名单 oracle_oracle_ocm
  4. unity快速接入第三方sdk_直播美颜SDK实现需要具备哪些条件
  5. mysql 哨兵模式_Redis讲解主从复制和哨兵模式
  6. c语言编程后总有一个错误,C语言编程,之后出现错误,请大神帮忙看下什么问题?...
  7. 龙芯.NET正式发布 开源共享与开发者共成长
  8. 公交换乘系统c语言,公交换乘的简单实现(源码)
  9. 单账户登录踢人 php,踢人下线
  10. 1042 mysql57_一次处理DB2宕机的实战经历(SQL1042C )
  11. 华擎 j3455 时钟 linux,经验 篇一:华擎J3455 硬改MAC地址
  12. FreeBSD搭建Nginx+Apache24+php56+mysql56手把手一步步的笔记
  13. VR全景智慧城市虚拟现实三维的发展
  14. specification jpa 复杂查询
  15. 《惢客创业日记》2019.01.23(周三) 太苦涩的人生也会让人麻木
  16. git版本回退命令_git 版本回退 撤销 删除
  17. 纽约大学计算机和信息科学专业,纽约大学与罗切斯特大学计算机科学专业比较...
  18. h264_nvenc GPU硬件编码与硬件加速
  19. EF Power Tools参数不正确的解决方法
  20. Sparrow Recsys

热门文章

  1. MySQL基础之数据类型介绍
  2. BUUCTF(pwn)jarvisoj_fm --格式化字符串漏洞
  3. Python 数据处理函数 round()、int()、floor()、ceil()的用法
  4. 在Python中为什么切片要忽略最后一个元素?
  5. Python基础教程:return函数的用法
  6. Python排序函数用法
  7. Django 知识补漏单例模式
  8. java数组最大下标_【Java视频教程】day09-面向对象
  9. docker如何实现重新打tag并删除原tag的镜像([仓库名: tag] 可以查询到指定id的镜像,同一个id镜像能有多个[仓库名: tag])(增加\删除镜像仓库:标签)
  10. VisualStudio opencv配置