一起来啃犀牛书:正则表达式
《javascript权威指南》这本书就像是js界的圣经,对于大神和新手都应该是必读书。但是这本近千页的书已经厚到让人望而生畏,要通读它不仅要时间也需要毅力。为了提升自己在js语言上的深度,所以抱着工匠精神开始研读,此文包含书中实用性较强的一些知识点和代码,算做读书笔记吧~
<!-- more -->
正则表达式这一章一直是我最困惑的,因为每次看完都会忘。。。所以这次我首先对知识点进行了梳理,然后配上习题练习,以此巩固。
从js正则表达式示意图可以看出,正则表达式分两块,一是声明定义二是函数调用。声明定义又可以分3块一是直接字符和字符类,然后是对字符(类)的描述,如重复、分组等,最后是修饰符,如大小写、全局匹配等。函数调用分为字符串用到正则表达式的函数和RegExp对象的原型函数。
js中可以使用构造函数来创建也可以使用斜杠。
var pattern = /s$/;
//等价于
var pattern = new RegExp('s$');
但是注意,在ES5规范中正则表达式和字符串常量不一样,每次声明都会重新创建变量,所以/s$/!==new RegExp('s$')
。
\o NUL字符(\u0000)
\t 制表符(\0009)
\n 换行符(\000A)
\v 垂直制表符(\u000B)
\f 换页符(\000C)
\r 回车符(\000D)
\xnn 十六进制拉丁字符
\uxxxx十六进制unicode字符
\cX 控制字符
这些转义字符中比较常用的就是换行符了,其他记不住可以上网查。还有一些字符具有特殊含义,如果需要匹配这些字符的时候需要在前面加上反斜杠进行转义。
^ $ . * + ? = ! : | \ / ( ) [ ] { }
[...] 方括号内任意字符
[^...] 不在方括号内任意字符
. 除换行符和其他unicode行终止符之外的任意字符
\w 等价于[a-zA-Z0-9]
\W 等价于[^a-zA-Z0-9]
\s 任何unicode空白符
\S 任何非unicode空白符
\d 等价于[0-9]
\D 等价于[^0-9]
[\b] 退格
这个字符类很重要,需要记忆。
描述方式:重复知识点
{n,m} 匹配前一项至少n次,不超过m次
{n,} 匹配前一项至少n次
{n} 匹配前一项n次
? 等价于{0,1}
+ 等价于{1,}
* 等价于{0,}
x? 描述符后跟随一个"?"表示非贪婪匹配:从字符串中第一个可能匹配的位置,尽量少的匹配。如“??”、“{1,5}?”等。
习题
-
匹配2~4个数字
-
精确匹配3个单词和一个可选数字
-
匹配前后带有一个或多个空格的字符串"java"
- 匹配一个或多个非左括号的字符
“|”与逻辑表达式中的或类似,前后两者任意一个匹配,很好理解。而圆括号用来分组和引用,功能就比较复杂了。
- 把单独的项组合成子表达式,以便重复、选择等操作。
- 完整的模式中定义子模式,从而在匹配成功后从目标串中抽出和圆括号中的子模式匹配的部分。
- 同一个正则表达式中后部引用前部的正则表达式,注意因为子表达式可以嵌套,所以它的位置是参与计数的左括号的位置。如果不创建带数字编码的引用,可以用"(?"和")"表示。
举个简单的例子,如果要匹配单引号或双引号中的字符,可能会写成下面这样:
/['"][^'"]*['"]/
但是如果我们是想成对的匹配'abc'而不是匹配'abc"的话需要这么改写:
/(['"])[^'"]*\1/
习题
匹配浮点数
锚指定匹配位置的元素称为锚。
^ 匹配字符串开头,多行匹配一行的开头
$ 匹配字符串结尾,多行匹配一行的结尾
\b 匹配一个单词的边界,位于\w和\W之间的位置
\B 匹配非单词边界
(?=p) 要求接下来的字符都与p匹配,但不能包括匹配p的那些字符
(?!p) 要求接下来的字符不与p匹配
这个"^"似曾相识?嗯,它在"[]"内的时候表示逻辑非,而在其它地方就成了锚字符了。
"\b"在"[]"中表示退格符,其它地方单词边界。怎么理解呢?比如我们想匹配"java"这个单词,那么我们如果只写/java/肯定是不行的,因为会匹配上javascript这类单词。那么加上空格符/\sjava\s/匹配呢?这样做也是有问题的,一个是多行情况下行首尾没有空格就匹配不了,二是实际上我们想得到的匹配字符串是"java"而不是带空格的" java "。所以这个时候就需要单词边界来表示/\bjava\b/。而\B正好相反。
而之后的断言不知道有什么妙用,看起来
(?=p)
//等价于
p
(?!p)
//等价于
[^p]
修饰符
- i。忽略大小写
- m。多行匹配模式
- g。全局匹配
查找匹配的字符串,不支持全局匹配,返回第一个子串的起始位置。
"JavaScript".search(/script/i) //4
返回由匹配结果组成的数组,默认返回第一个匹配的字符串,如果全局匹配则返回所有匹配字符串。当使用括号分组的时候第一个元素为匹配的字符串,其后为圆括号中各个匹配的子字符串。
"1 add 2 add 3".match(/\d/) //["1"]
"1 add 2 add 3".match(/\d/g) //["1", "2", "3"]
"https://yalishizhude.github.io/index.html".match(/(\w+)\:\/\/([\w.]+)\/(\S*)/); //["https://yalishizhude.github.io/index.html", "https", "yalishizhude.github.io", "index.html"]
这是将字符串转化为数组的方法。一般用字符串做分隔符匹配,如果使用正则表达式,则在匹配字符串的前后方断开。同时注意以下几点:
- 匹配到开头内容,返回数组第一个元素为空字符串。
- 匹配到结尾内容,返回数组最后一个元素为空字符串。
- 未匹配,返回数组只包含未切分的字符串。
- $n 匹配第n个匹配正则表达式中的圆括号子表达式文本
- $& 匹配正则表达式的子串
- $` 匹配子串左边的文本
- $' 匹配子串右边的文本
- $$ 匹配美元符号
"z d l".replace(/(\w)\s(\w)\s(\w)/, '$3 $2 $1') // "l d z"
习题
中文双引号替换英文双引号
RegExp对象 属性- source 正则表达式文本
- global 只读布尔值,是否有修饰符g
- ignoreCase 只读布尔值,是否有修饰符i
- multiline 只读布尔值,是否有修饰符m
- lastIndex 下一次检索开始的位置,用于exec()和test()
方法
exec()
类似String.match,不过不能使用全局匹配。匹配同时修改lastIndex值为紧挨着匹配子串的字符位置,如果未匹配则为0。
test()
返回布尔值,可以修改lastIndex从指定位置开始匹配。
正则表达式学习起来就4个字:死去活来~原理并不复杂,概念理解清楚了,基础知识记清楚了,一般的表达式应该都能写了~
习题答案和百度脑图下载地址:http://yalishizhude.github.io/subscribe/
博客:http://yalishizhude.github.io
作者:亚里士朱德
共同学习,写下你的评论
评论加载中...
作者其他优质文章