回顾
有一个东西,就是因为它,使得它所在的作用域不被释放,它是就是闭包。
0、目标
1、能够掌握正则表达式的语法(涉及到的内容,最起码会查手册)
2、能够理解什么是捕获和引用
3、能够匹配中文
4、能够查阅正则对象中内置的方法
5、能够查阅字符串对象中支持正则的方法
6、能够在PHP中使用正则
一、概述
w3c手册位置:上面的Javascript --- 左侧的Javascript --- 右侧的参考书 --- 左侧的JS RegExp
或者:上面的Javascript --- 右侧的Javascript --- 左侧的JS RegExp
正则表达式(regular expression)描述了一种字符串匹配的模式,可以用来检查一个字符串中是否含有某种子串、将匹配的子串做替换或者从某个字符串中取出符合某个条件的子串等。
匹配就是在某个字符串中查找你想要查找的内容(由正则表达式决定),如果查找到了,就表示匹配。没有查找到就表示不匹配。
正则表达式本身是一门独立的技术,可以被大多数编程语言所使用,如Javascript、PHP、Java…
正则表达式也是用于查找字符串的,只是比正常的查找更加高级。
比如在字符串“abacad”中查找a:
Javascript语法:'abacadabacad'.search('a');
php语法:strpos('abacad', 'a');
如果查询条件是下面的条件,用普通的查询就不能完成了。
要求查找a,什么样的a呢?后面必须是b的a。这正是正则表达式的用武之地。
(1)表单验证里面,验证字符的合法性,如邮箱是否合法,手机号是否合法等等。
(2)信息过滤,如论坛帖子或者评论中的非法字符,例如 sql注入、js脚本注入、煽动性的言论。
(3)信息采集,采集别人网站上面的内容,例如整页采集时 筛选出需求的部分。
(4)信息替换。
(5)页面伪静态的规则。
二、入门案例
输出结果:
没匹配的情况:
没有匹配,返回null。
g是global,表示全局的意思,它是正则表达式语法中的修饰符,修饰符应该放到定界符(/)的后面。
输出结果:
三、正则语法
n+ 匹配任何包含至少一个 n 的字符串。匹配一个或多个前导字符(前导字符就是紧挨着+的前一个字符)
n* 匹配任何包含零个或多个 n 的字符串。前导字符有没有都行
n? 匹配任何包含零个或一个 n 的字符串。
n{X} 匹配包含 X 个 n 的序列的字符串。
n{X,Y} 匹配包含 X 到 Y 个 n 的序列的字符串,包括X和Y个
n{X,} 匹配包含至少 X 个 n 的序列的字符串。
n$ 匹配任何结尾为 n 的字符串。从末尾开始匹配
^n 匹配任何开头为 n 的字符串。(注意位置在前面)
^n$ 表示只匹配字符串n。也就是匹配整个字符串。
. 表示单个字符,表示任意字符。除了换行和行结束符。
.* 表示任意字符串(0个或多个任意字符,除了换行和行结束符).是任意一个字符,*表示任意个前导字符。二者组合表示任意字符串
\w 匹配任何数字、字母、下划线。一个\w表示一个字符。
\W 匹配任何非数字、非字母、非下划线。
\d 查找数字。
\D 查找非数字字符。
\s 查找空白字符。
\S 查找非空白字符。
\b 匹配单词边界。(边界字母个数没有限制;\b放前面表示匹配单词前面的边界,\b表示匹配单词后面的边界)
\B 匹配非单词边界。
\n 查找换行符。
\r 查找回车符。
\t 查找制表符。
方括号表示一个范围,也称为字符簇。
[abc] 查找方括号之内的任何字符。
[^abc] 查找任何不在方括号之间的字符。(方括号中的^表示取反)
[0-9] 查找任何从 0 至 9 的数字。表示一个字符
[a-z] 查找任何从小写 a 到小写 z 的字符。
[A-Z] 查找任何从大写 A 到大写 Z 的字符。
[A-z] 查找任何从大写 A 到小写 z 的字符。包括下划线。
[5-8] 查找5 <= 目标 <= 8的字符
(red|blue|green) 查找任何指定的选项。(竖线|表示或者)
修饰符的用法,是修饰符一定要写到//之后,可以一次性使用多个修饰符。
i 执行对大小写不敏感的匹配。实际上就是不区分大小写的匹配
g 执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。
m 执行多行匹配。
如果匹配的字符串在正则中有特殊含义的都必须加转义字符。如[]$.*?+|^{}()
但是不要乱加转义。
四、分组/捕获和反向引用
捕获和反向引用的语法的解释:
正则中出现的小括号,就叫捕获或者分组
在正则语法中(在/…/内),在捕获的后面,用“\1”来引用前面的捕获。用\2表示第二个捕获的内容….
在正则语法外(如replace时),用“$1”来引用前面的捕获。
禁止引用
(?:正则) 这个小括号中的内容不能够被引用
五、匹配中文(utf-8编码)
每个字符(中文、英文字母、数字、各种符号、拉丁文、韩文、日文等)都对应着一个Unicode编码。
查看Unicode编码,找到中文的部分,然后获取中文的Unicode编码的区间,就可以用正则匹配了。
前面我们用[a-z]表示小写字母,[0-9]表示数字,这就是一个范围表示,如果有一个数x能够表示第一个中文,有一个数y能够表示最后一个中文,那么[x-y]就可以表示所有的中文了。
中文的Unicode编码从4E00开始,到9FA5结束。
[4E00-9FA5]这个区间就能够表示中文。
JS语法:[\u4e00-\u9fa5]
完整的Unicode编码表:http://blog.csdn.net/hherima/article/details/9045861
六、环视(断言/零宽断言/正向预测/负向预测)
every(?=n) 匹配任何其后紧接指定字符串 n 的字符串。
有一个字符串是“abacad”,从里面查找a,什么样的a呢?后面必须紧接b的a。
正则语法是:/a(?=b)/g
延伸一下,案例中的a、b都是正则表达式,实际上换一个复杂一点的正则表达式也是可以的。
every(?!n) 匹配任何其后没有紧接指定字符串 n 的字符串。
有一个字符串是“abacad”,从里面查找a,什么样的a呢?后面不能紧接b的a。
正则语法是:/a(?!b)/g
另外,还会看到(?!B)[A-Z]这种写法,其实它是[A-Z]范围里,排除B的意思,前置的(?!B)只是对后面数据的一个限定,从而达到过滤匹配的效果。
七、正则对象的属性和方法
正则对象中的成员方法和属性的正确调用方式:
和String对象类似:
- 一种是直接量语法(/[a-z]/.exec())
- 另一种方法是实例化正则对象,然后通过对象去调用成员方法(var reg = new RegExp(/[a-z]/); reg.exec())
类似字符串:
①、&#39;hello&#39;.substr(1);
②、var s = new String(&#39;hello&#39;); s.substr(1);
exec方法执行一个正则匹配,只匹配一次,匹配到结果就返回一个数组类型的结果,匹配不到就返回null。并将表示匹配的位置 置为下一个匹配的位置。
lastIndex一个整数,标示开始下一次匹配的字符位置。没有更多匹配重置lastIndex为0.
依次调用exec匹配下一个的例子:
依次调用exec,会将匹配的位置不断的后移,直至结尾。
匹配带子表达式的例子,带子表达式并且依次调用的例子:
依次调用,依然匹配下一个:
test方法检测目标字符串和正则表达式是否匹配,如果匹配返回true,不匹配返回false。
八、支持正则表达式的 String 对象的方法
在字符串中搜索符合正则表达式的结果。如果找到结果返回结果的位置,停止向后检索,也就是说忽略全局标识符g;如果没有匹配结果,返回-1.
在字符串中检索匹配正则表达式的子串;如果匹配,返回包含匹配结果的一个数组;不匹配返回null。
不加全局g的情况:
获取的结果只是第一个匹配的内容,匹配的内容中的第一个单元是匹配的结果,后面的单元是子表达式
带子表达式的情况:
加全局的g的情况:
获取的结果是所有匹配的内容,但是不包含子表达式。
多次调用和调用一次效果一样。
将字符串分割成数组:
特点是可以用正则表达式来分割字符串。
默认只替换一次,加g全部替换。加入全局的g:
替换的时候,使用"$1"表示第一个子表达式:
用$2表示第二个子表达式,以此类推。
替换abc为a[a-b-c]c ghk à g[g-h-k]k
用 $`表示捕获的内容左侧的内容 用$&#39;表示捕获的内容右侧的内容
替换aaa bbb ccc为Aaa Bbb Ccc
演示可以用函数来进行复杂的替换。
九、案例
采用的方法是:正则对象中的test方法。
手机号格式:
11位
纯数字
1开头
[23为判断] -- 去各大运营商查询有哪些号段
//先自己练习
把“今今今天晚晚晚晚晚晚上吃吃吃吃吃吃鸡”字符串换成单字的形式,即“今天晚上吃鸡”;
注册的时候,要求用户名:长度4~10位,不能是纯数字,不能是纯字母,不能有特殊符号,不能以数字打头。
十、PHP中的正则表达式
语法和Javascript中的正则语法基本一致。
PHP中的正则函数:
preg_match()返回匹配的次数,它的返回值是0或者是1.
0表示不匹配。
1表示匹配一次,因为preg_match在匹配一次之后就停止向后检索了。
查看匹配的结果:
带有子表达式的例子:
执行正则表达式的全局匹配,类似于js中的带g的匹配。
带有子表达式的例子:
替换字符串:
替换数组:
案例:解决贪婪问题?
匹配的思路是一样的,也是查看Unicode编码表。
但是语法稍有不同
PHP中的使用正则的使用除了//以外,外面还要加引号,这个引号要用单引号。