1.背景介绍
字符串是编程时涉及到的最多的一种数据结构,对字符串进行操作的需求几乎无处不在。比如判断一个字符串是否是合法的Email地址,虽然可以编程提取 @ 前后的子串,再分别判断是否是单词和域名,但这样做不但麻烦,而且代码难以复用。
正则表达式是一种用来匹配字符串的强有力的武器。它的设计思想是用一种描述性的语言来给字符串定义一个规则,凡是符合规则的字符串,我们就认为它“匹配”了,否则,该字符串就是不合法的。
2.知识剖析
1.如何写正则表达式
第一种使用字面量形式来定义正则表达式
var reg = /[bc]at/i;
第二种是用RegExp构造函数
var reg = new RegExp("[bc]at","i/g/m");
在这里需要注意的是:
1.在var reg = /[bc]at/;的后面,不光可以+i,还可以把其他的都加上:var reg = /[bc]at/igm;
2.var reg = new RegExp();中可以调用已有的正则:var reg1 = new RegExp(reg);
3.
var aaa = /abc/igm;
var aaa1 = new RegExp(aaa);
在上面的代码中虽然aaa1引用了aaa,但是aaa1与aaa是互相独立的。
但是
var aaa = /abc/igm;
var aaa1 = RegExp(aaa);
如果把前面的new去掉,那么aaa与aaa1则是相关联的,改动aaa,aaa1也会跟着改。
当然,也不会有人用RepExp构造函数写,不加new。这里只是提一下,不加new会怎样。
2.修饰符
修饰符用于执行区分大小写和全局匹配:
修饰符 i 对大小写不敏感
var reg = /aaa/i;
var str = "AAA";
console.log(reg.test(str));
返回结果为true
修饰符 g,执行全局匹配。例子如下:
var reg = /aaa/g;
var str = "AAAaaaaaaaa";
console.log(str.match(reg));
选中所有符合"aaa"的字符,返回结果为 ["aaa", "aaa"]。
但是如果不加g,则只能返回一个 "aaa"
修饰符 m执行多行匹配
大概意思就是,如果字符串中有换行,在前一行匹配完之后会在下一行继续进行匹配(不加修饰符g的前提下)
3.方括号
方括号用于查找某个范围内的字符:
例如:
var reg = /[bc]at/g;
可以匹配: bat、cat
[]中只表示一个在某一个位置的范围
[]中的 " ^ ",表示的是“非”的意思。比如:
[^a]表示:除开 a 以外的东西。
4.元字符
元字符(Metacharacter)是拥有特殊含义的字符:
元字符 | 描述 |
---|---|
. | 查找单个字符,除了换行和行结束符。 |
\w | 查找单词字符。 |
\W | 查找非单词字符。 |
\d | 查找数字。 |
\D | 查找非数字字符。 |
\s | 查找空白字符。 |
\S | 查找非空白字符。 |
\b | 匹配单词边界。 |
\B | 匹配非单词边界。 |
\0 | 查找 NULL 字符。 |
\n | 查找换行符。 |
\f | 查找换页符。 |
\r | 查找回车符。 |
\t | 查找制表符。 |
\v | 查找垂直制表符。 |
\xxx | 查找以八进制数 xxx 规定的字符。 |
\xdd | 查找以十六进制数 dd 规定的字符。 |
\uxxxx | 查找以十六进制数 xxxx 规定的 Unicode 字符。 |
这里需要注意的一点是:
\s 可以匹配 \n + \f + \r + \t + \v 以及 (空格)
var reg = /\s/;
var str = "\t\n\r\v\f ";
console.log(reg.test(str));
返回结果为:true
其次:
var reg = /\tc/;// \t 匹配制表符
var str = "ab c"; //会显示无法匹配 字符串中得是 "\tc"才匹配得到。
console.log(reg.test(str));
上面代码中ab到c的这一空断是用了tab打出来的
而\t就是用来匹配制表符的。
会发现返回结果为 flase
把这个 tab键 打出来的空,用 \t 代替
var reg = /\tc/;
var str = "ab\tc";
console.log(reg.test(str));
返回为true
另外:如果我想要匹配全部,该怎么写?
上面的元字符多少都有限制,无法匹配全部
答案就是:
var reg = /[\d\D]/g;
他和他自己的补集就可以匹配全部了
5.量词
量词 | 描述 |
---|---|
n+ | 匹配任何包含至少一个 n 的字符串。 例如,/a+/ 匹配 "candy" 中的 "a","caaaaaaandy" 中所有的 "a"。 |
n* | 匹配任何包含零个或多个 n 的字符串。 例如,/bo*/ 匹配 "A ghost booooed" 中的 "boooo","A bird warbled" 中的 "b",但是不匹配 "A goat grunted"。 |
n? | 匹配任何包含零个或一个 n 的字符串。 例如,/e?le?/ 匹配 "angel" 中的 "el","angle" 中的 "le"。 |
n{X} | 匹配包含 X 个 n 的序列的字符串。 例如,/a{2}/ 不匹配 "candy," 中的 "a",但是匹配 "caandy," 中的两个 "a",且匹配 "caaandy." 中的前两个 "a"。 |
n{X,} | X 是一个正整数。前面的模式 n 连续出现至少 X 次时匹配。 例如,/a{2,}/ 不匹配 "candy" 中的 "a",但是匹配 "caandy" 和 "caaaaaaandy." 中所有的 "a"。 |
n{X,Y} | X 和 Y 为正整数。前面的模式 n 连续出现至少 X 次,至多 Y 次时匹配。 例如,/a{1,3}/ 不匹配 "cndy",匹配 "candy," 中的 "a","caandy," 中的两个 "a",匹配 "caaaaaaandy" 中的前面三个 "a"。注意,当匹配 "caaaaaaandy" 时,即使原始字符串拥有更多的 "a",匹配项也是 "aaa"。 |
n$ | 匹配任何结尾为 n 的字符串。 |
^n | 匹配任何开头为 n 的字符串。 |
?=n | 匹配任何其后紧接指定字符串 n 的字符串。 |
?!n | 匹配任何其后没有紧接指定字符串 n 的字符串。 |
这里需要注意的是
当^与$一起用时,则表示整行匹配
var reg = /^abc$/g;
var str = "abcdc";
console.log(reg.test(str));
返回为flase.
按照之前的写法,var reg = abc中的 abc 应该是与字符串中的"abc",相匹配的。但是加上^$之后则要求从头到尾都要一样。
?=n与?!n又叫正向预查
//正向预查
var str = "abaaaaa";//想选中后面有b的a 不选中b
var reg = /a(?=b)/g;
例如上面的例子,表示 匹配后面没有b的a,但又不选中b。
返回结果只有一个 a
6.RegExp 对象方法
方法 | 描述 |
---|---|
compile | 在 1.5 版本中已废弃。 编译正则表达式。 |
exec | 检索字符串中指定的值。返回找到的值,并确定其位置。 |
test | 检索字符串中指定的值。返回 true 或 false。 |
toString | 返回正则表达式的字符串。 |
test用法:
var reg = /aa/g;
var str = "aabaa";
reg.test(str);
判断字符串有没有符合要求的片段。返回结果只能是true或flase
exec,检索字符串中指定的值。返回找到的值,并确定其位置
例如:
var reg = /ab/g;
var str = "abababab";
console.log(reg.exec(str));
console.log(reg.exec(str));
console.log(reg.exec(str));
console.log(reg.exec(str));
结果:
index中的数字就是ab出现的位置
这里还要介绍一个:
lastIndex
他与exec()是互相辅助的
可以通过 reg.lastIndex来指定位置,然后用.exec()指定的位置上进行检索
var reg = /ab/g;
var str = "abababab";
reg.lastIndex = 2;
console.log(reg.lastIndex);
console.log(reg.exec(str));
当然,这一切都还有个前提,那就是 var reg = /ab/g;中 /ab/后面的g(是建立在全局中的)
7.支持正则表达式的 String 对象的方法
方法 | 描述 | FF | IE |
---|---|---|---|
search | 检索与正则表达式相匹配的值。 | 1 | 4 |
match | 找到一个或多个正则表达式的匹配。 | 1 | 4 |
replace | 替换与正则表达式匹配的子串。 | 1 | 4 |
split | 把字符串分割为字符串数组。 |
split、search示例如下
var reg = /ab/g;
var str = "abababab";
console.log(str.search(reg));//匹配成功则返回位置值,否则返回-1
console.log(str.split(reg));//split拆分字符串,括号里面可以填字符串,还可以填正则表达式需要
需要注意的是:
.search匹配成功后就会返回值,不会再往后匹配了,哪怕是在正则表达式后加了g.
replace
str.replace("a","b"); //b替换a。没有访问全局的能力,只能访问一个。
但如果在正则后面加了 g,则可以全部替换
var reg = /a/g;
var str = "aa";
console.log(str.replace(reg,"b"));
输出结果为 bb
其他情况的举例
var reg = /(\w)\1(\w)\2/;
var str = "aabb";
console.log(str.replace(reg,"$2$2$1$1"));//$2:表示引用第二个子表达式
console.log(str.replace(reg,function($,$1,$2){//第一个$表示的是全局,是必须要的。这个函数系统自动调用,还会自动传参。本例用$表示
return $2 + $2 + $1 + $1 + "asd";//return用来返回一个字符串
}));
// str.toUpperCase() 字符串变大写
// str.toLowerCase() 变小写
8.RegExp 对象属性
属性 | 描述 |
---|---|
constructor | 返回一个函数,该函数是一个创建 RegExp 对象的原型。 |
global | 判断是否设置了 "g" 修饰符 |
ignoreCase | 判断是否设置了 "i" 修饰符 |
lastIndex | 用于规定下次匹配的起始位置 |
multiline | 判断是否设置了 "m" 修饰符 |
source | 返回正则表达式的匹配模式 |
3.常见问题
如何用正则匹配全部?
4.解决方案
/var reg = /[\d\D]/g;
选中一个元字符比如: \d 他和他自己的补集就可以匹配全部了。
5.编码实战
6.拓展思考
正则匹配的 贪婪模式和非贪婪模式
var str = "aaaaa";
var reg = /a+?/g; //有多个就不会匹配一个,贪婪模式
console.log(str.match(reg));
var reg = /a+?/g; //在量词后面加上?,就是非贪婪模式
var reg = /a{1,3}?/g; //优先取1
var reg = /a??/g; //第一个是选取0或1,第二个?是取消贪婪匹配
7.参考文献
《JavaScript高级程序设计》
廖雪峰:
CSDN:https://blog.csdn.net/zaifendou/article/details/5746988
8.更多讨论
1.如何使用正则来让那些规定的和谐子被和谐
使用replace()方法
var str =“傻子”;
var reg =/傻/g; //定义正则
str.replace(reg,"*") //输出 *子
2.如何使用正则来检测qq号是否符合
var reg = /^[1-9]\d{4,12}/ //定义正则
使用test()方法来检测
reg.test(字符串)
3.字符串“100000000”如何把它变成100.000.000
var str = "100000000";//如何变成100.000.000
var reg = /(?=(\B)(\d{3})+$)/g;
console.log(str.replace(reg,"."));
4. $ 与 ^
^ 在[]中表示的是"非"的意思。在量词中表示的是必须以什么开头。
$ 在replace中表示的是引用子表达式。在量词中表示的是必须以什么结尾
鸣谢
感谢大家观看