js正则表达式详细解析
正则表达式:又叫做规则表达式(Reglur Excepression),计算机科学的一个概念,通常被用来检索、替换符合某个模式的文本。正则表达式这个概念最初由Unix中的工具软件普及开来,通常缩写为regexp,正则表达式在很多地方都会被用到例如java,js中,本文介绍的是正则表达式在js中的灵活运用,正则表达式是比较复杂晦涩的知识,也因为它的晦涩难懂,所以我会尽量写的简单易懂,让读者更容易明白,只要认真学习,没什么能难倒你。
一.创建正则表达式
1.目前有两种方式创建正则表达式对象:
var reg1 = /pattern/flag; 例如var reg = /^\d+$/g (匹配纯数字至少一个,例如1,11,111,1111)
var reg2 = new RegExp(pattern,flag); 例如var reg = new RegExp("^\\d+$","g"); 意义同上,此处\是特殊字符,需要转义为\\。
注: reg1,reg2就是正则表达式对象,对象有属于自己的属性和方法,下面会有介绍
pattern 描述了表达式的模式/规则
flag 用于指定全局匹配、区分大小写的匹配和多行匹配
2.对象拥有的属性
global:如果设置了new RegExp(pattern,g); g被设置后, global属性为true
ignoreCase:同上,代表i(大小写不敏感)同
multiline:同上,代表m,多行匹配
lastIndex:代表匹配到的下标的下一位
Source:源文本
3.对象可以使用的方法:
test(参数):方法检索字符串中的指定值。返回值是true或false。
exec(参数) :方法检索字符串中的指定值。返回值是一个数组。如果没有发现匹配,则返回null
解释:如果 exec()找到了匹配的文本,则返回一个结果数组。否则,返回null。此数组的第0个元素是与正则表达式相匹配的文本, 第 1个元素是与reg的第 1个子表达式相匹配的文本(如果有的话),第2个元素是与reg的第 2个子表达式相匹配的文 本 (如果有的 话),以此类推。除了数组元素和 length属性之外,exec()方法还返回两个属 性。index属性声明的是匹配文本的第一个字符的 位 置。input属性则存放的是被检索的字符串string。我们可以看得出, 在调用非全局的RegExp对象的exec()方法时,返回的数组与调用 方 法 String.match()返回的数组是相同的。
但是,当reg是一个全局正则表达式时,exec()的行为就稍微复杂一些。它会在RegExpObject的lastIndex 属性指定的字符处开始检索字符串 string。当exec()找到了与表达式相匹配的文本时,在匹配后,它将把RegExpObject 的lastIndex属性设置为匹配文本的最后一个字符的下一个位置。这就是说,您可以通过反复调用 exec()方法来遍历字符 串中的所有匹配文本。当exec()再也找不到匹配的文本时,它将返回null,并把lastIndex属性重置为0。
compile():此方法将pattern 转换为内部的格式,从而执行得更快。例如,这允许在循环中更有效地使用正则表达式。当重复使用相同的表达式时,编译过的正则表达式使执行加速。然而,如果正则表达式发生更改,则这种编译毫无益处。
4. pattern 和flag详细介绍
Flag的选择有以下三种:
i 执行对大小写不敏感的匹配, 比如var reg = /e/i reg.test("E")返回为true,因为i忽略大小写
g 执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。
m 执行多行匹配。
pattern组成:((方括号表达式|元字符)*量词)*
规则: 1,方括号表达式-->代表一个字符
2,元字符 -->代表一个字符
3,量词 -->代表多个字符
方括号表达式:查找到任何一个就返回true-->一个
[abc] 查找方括号之间的任何字符.
[^abc] 查找任何不在方括号之间的字符。
[0-9] 查找任何从0至 9 的数字。
[a-z] 查找任何从小写a到小写z的字符。
[A-Z] 查找任何从大写A到大写Z的字符。
[A-z] 查找任何从大写A到小写z的字符。
(red|blue|green)找三个单词中任意一个。
元字符:-->一个
. 查找单个字符,除了换行和行结束符。 想表示字符.可以转义
\w 查找单词字符。字母 数字_
\W 查找非单词字符。非 字母 数字_
\d 查找数字。
\D 查找非数字字符。
\s 查找空白字符。
\S 查找非空白字符。
\b 匹配单词边界。
\B 匹配非单词边界。
\0 查找NUL字符。
\n 查找换行符。
\f 查找换页符。
\r 查找回车符。
\t 查找制表符。
\v 查找垂直制表符。
量词:-->控制用多个
n+ 匹配任何包含至少一个n的字符串。
n* 匹配任何包含零个或多个n的字符串。
n? 匹配任何包含零个或一个n的字符串。
n{X} 匹配包含X个 n 的序列的字符串。
n{X,Y} 匹配包含X至 Y 个 n 的序列的字符串。
n{X,} 匹配包含至少X个 n 的序列的字符串。
n$ 匹配任何结尾为n的字符串。
^n 匹配任何开头为n的字符串。
?=n 匹配任何其后紧接指定字符串n的字符串。var patt = /ll(?=o)/;
?!n 匹配任何其后没有紧接指定字符串n的字符串。
二:一些常用的正则表达式(本人亲自测试过):
0:纯数字: /^[0-9]$/或者/^\d$/
1.匹配1到6个汉字(用来验证姓名):/^[\u4e00-\u9fa5]{1,6}$/
2.验证身份证(15数字或者18位数字或者17位数字加一位校验位,校验位可能为大写字母或者数字):
/(^\d{15}$)|(^\d{17}(([A-Z]$)|([0-9]$)))/
3.(强密码校验)必须包含英文字母大小写,数字,允许特殊字符,6到10位:
/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,10}$/
可以看作 /^(?=(.*\d))(?=(.*[a-z]))(?=(.*[A-Z])).{6,10})$/ (此处注意?=的用法,请参照上面的内容)
4.密码验证进阶版:要求如下(这是访问我们公司用户资源登录口令的要求,比较变态,如果你能独立写完这个式子,你的正则表达式基本可以毕业了)
a.8位或以上长度,最多12位
b.包含来自以下四个类别中的三类(即至少三类)
大写英文字母(从A到Z)
小写英文字母(从a到z)
10个基本数字(0到9)
非字母字符(例如&,%,@,#,^等等)
题目分析:这里的最难的点在于b的要求,四类中包含三类,也就是说最少三类,可以四类。从正面分析情况很多:如果把b的要求分为1,2,3,4.那么可能组合的情况123,124,134,234,1234,这里产生了五种情况,每种情况都要考虑到,
/^(((?=.*\d)(?=.*[a-z])(?=.*[A-Z]))|
((?=.*\d)(?=.*[a-z])(?=.*[&%@#^]))|
((?=.*\d)(?=.*[&%@#^])(?=.*[A-Z]))|
((?=.*[a-z])(?=.*[A-Z])(?=.*[&%@#^]))).{6,10}$/;
虽然写了出来,不过确实有点复杂,匹配也比较耗费时间,这也是正则表达式的弊端,太过复杂并且面对复杂的查询条件(比如“或”情况较多的时候)显得有些吃力,实际开发中也不建议写过长的正则表达式。
4.腾讯qq号码校验(非0开头,最少5位,目前最多12位): /^[1-9][0-9]{4,11}/
5.邮箱验证:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
6.匹配正整数:^[1-9]\d*$
7.匹配负整数:^-[1-9]\d*$
8.验证国内移动号码(11位):
移动号段:139,138,137,136,135,134,150,151,152,157,158,159,182,183
电信号段:130,131,132,136,185,186,145
联通号段: 133,153,180,189
表达式:/^1[3|4|5|8][0-9]{9}$/
9.匹配国内的电话号码(如0511-4405222或 021-87888822两种形式,网上随便搜都有)
\d{3}-\d{8}|\d{4}-\d{7}
10.匹配空白行:\n\s*\r
11.匹配双字节字符:/[^\x00-\xff]/
12.匹配正浮点数:/^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$/
13.匹配负的浮点数: /^-[1-9]\d*\.\d*|-0\.\d*[1-9]\d*$/
14.匹配常用的网址:/^[a-zA-z]+://[^\s]*$/
以 下是我自己写的一个简单验证昵称和密码的界面,需要请参考: