【修真院小课堂】正则表达式

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高级程序设计》

廖雪峰:

https://www.liaoxuefeng.com/wiki/001434446689867b27157e896e74d51a89c25cc8b43bdb3000/001434499503920bb7b42ff6627420da2ceae4babf6c4f2000

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中表示的是引用子表达式。在量词中表示的是必须以什么结尾

鸣谢

感谢大家观看

猜你喜欢

转载自blog.csdn.net/weixin_42121231/article/details/81053883