js正则表达式
很多时候,我们对正则表达式的印象都是难学难记,学了又忘,忘了又学,但总觉得记不住。
什么是正则表达式?
正则表达式(Regular Expression)使用单个字符来描述、匹配一系列符合某个句法规则的字符串。
使用正则表达式的目的--替换工作。自己先定义一种规则,然后到字符串中去匹配一下符合这个规则的子字符串。
为了更好地理解正则表达式,我们可借助可视化工具,在线地址为:
Regexper:regexper.com
Regulex:jex.im/regulex/#!f…
Debuggex:www.debuggex.com/
先学习一下正则表达式的语法:
1、RegExp对象
js通过内置对象RegExp支持正则表达式,有2种方法实例化RegExp对象: a.字面量 b.构造函数
a.字面量
- var reg = /\bare\b/g;
如何进行全文匹配?☞“g”
b.构造函数
- var reg = new RegExp('\\bare\\b', 'g');
第1个参数:字符串☞正则表达式的文本,js中“\”本身就是特殊字符,想使用的话需要转义;
第2个参数:字符串☞标识。
全文匹配-->“g”:
修饰符
g:global--全文搜索,不添加,搜索到第一个匹配为止;
i:ignore case--忽略大小写,默认大小写敏感;
m:multiple lines--多行搜索。
发现:大写的单词未被替换,想要忽略大小写,无论大小写都能匹配☞“i”。
2、元字符
正则表达式由2种基本字符类型组成:1.原义文本字符, 2.元字符
元字符是在正则表达式中有特殊含义的非字母字符
* + ? $ ^ . | \ () {} []
3、字符类
一般情况下,正则表达式的一个字符对应字符串的一个字符。有时,希望匹配某类字符(即符合一系列特征的某类字符),该如何处理?
☞我们可以使用元字符[]来构建一个简单的类;
☞所谓类是指符合某些特性的对象,是一个泛指,而不是特指某个字符;
☞表达式[abc]把字符a或b或c归为一类,表达式可以匹配这类的字符。
字符类取反
a.使用元字符^创建反向类/负向类
b.反向类是指不属于某类的内容
c.表达式[^abc]表示不是字符a或b或c的内容
4、范围类
使用字符类匹配数字[0123456789]
可使用[a-z]来连接2个字符,表示从a到z的任意字符(这是个闭区间,即包含a和z本身)。
在[]组成的类内部是可以连写的[a-zA-Z]
问:“-”并不是特殊字符,也不是元字符,有时在类里就想要匹配“-”时该如何?
记住:“-”在中间,即一个开头,一个结尾这样的语法里,表示范围。
这样就可匹配“-”了。
5、预定义类
匹配一个ab+数字+任意字符的字符串
正则表达式还提供了几个常用的边界匹配符
发现:凡有“is”的地方都做了替换。
只想替换单词“is”,单词是有单词边界的。
若只想替换“This”中的is,观察发现:前边不是边界,后面才是边界,于是有
注意:元字符的含义并不是唯一的,在不同的场景下有不同的含义,不在[]里的含义就不是取反了,而是表示“以xx开始”。
“.@”☞“任意字符+@”进行匹配
“@.”☞“@+任意字符”进行匹配
“.@$”☞“只想让@作为结尾”进行匹配
6、量词
我们希望匹配一个连续出现n次数字的字符串,如“\d\d\d\d\d\d\d\d\d\d......”,为了解决这样的问题,正则表达式引入了量词的概念。
7、正则表达式的贪婪模式与非贪婪模式
a.贪婪模式
正则表达式在匹配时会尽可能多地匹配,直到匹配失败,默认是贪婪模式。
b.非贪婪模式
让正则表达式尽可能少地匹配,即一旦匹配成功就不再继续往下,这就是非贪婪模式。☞在量词后面加?即可。
8、分组
匹配字符串javascript连续出现3次的场景,若这样写javascript{3},如下
量词只能针对于紧挨着它的字母,并不能作为整个单词。使用( )可达到分组的功能,使量词作用于分组。
(javascript){3},如下
使用|可达到或的效果:
反向引用
2017-11-10 =>11/10/2017
替换的内容不再是常量,而是变量,此时该如何处理?☞“$”分组类的内容。
用"$1"等来代表捕获的分组,又叫分组捕获。
利用分组,但又不想捕获它,该如何?☞忽略分组
不希望捕获某些分组,只需要在分组内加上? :即可。
9、前瞻
正则表达式从文本头部向尾部开始解析,文本尾部方向,称为“前”,文本头部,称为“后”。
前瞻就是在正则表达式匹配到规则时,向前检查是否符合断言,后顾/后瞻方向反。
js不支持后顾。
符合特定断言称为肯定/正向匹配;不符合特定断言称为否定/负向匹配。
10、js对象属性
global:是否全文搜索,默认false。
ignore case:是否大小写敏感,默认false。
multiline:多行搜索,默认false。
lastIndex:是当前表达式匹配内容的最后一个字符的下一个位置。
source:正则表示式的文本字符串。
- var reg1 = /\w/;
- var reg2 = /\w/gim;
RegExp.prototype.test(str)☞用于测试字符串参数中是否存在匹配正则表达式模式的字符串。若存在则返回true,否则返回false。
- var reg1 = /\w/;
- var reg2 = /\w/g;
产生原因:受lastIndex影响。
- var reg1 = /\w/;
- var reg2 = /\w/g;
- while (reg2.test('ab')) {
- console.log(reg2.lastIndex);
- }
每次都只有第一遍是对的,于是,每次都给它实例化一个新的,但这需要用到内存开销。没必要这么做。
RegExp.prototype.exec(str)☞使用正则表达式模式对字符串执行搜索,并将更新全局RegExp对象的属性以反映匹配结果。
若没有匹配的文本则返回null,否则返回一个结果数组:
index声明匹配文本的第一个字符的位置
input存放被检索的字符串string
非全局调用
调用非全局的RegExp对象的exec()时,返回数组;
第一个元素是与正则表达式相匹配的文本;
第二个元素是与RegExpObject的第一个子表达式相匹配的文本(若有的话);
第三个元素是与RegExp对象的第二个子表达式相匹配的文本(若有的话),以此类推。
String.prototype.search(reg)
☞search()方法用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串;
☞方法返回第一个匹配结果index,查找不到返回-1;
☞search()方法不执行全局匹配,它将忽略标志g,且总是从字符串的开始进行检索。
String.prototype.match(reg)
☞match()方法将检索字符串,以找到一个或多个与regexp匹配的文本;
☞regexp是否具有标志g对结果影响很大。
非全局调用
若regexp没有标志g,则match()方法就只能在字符串中执行一次匹配;若未找到任何匹配的文本,将返回null,否则,它将返回一个数组,其中存放了与它找到的匹配文本有关的信息;返回数组的第一个元素存放的是匹配文本,而其余的元素存放的是与正则表达式的子表达式匹配的文本;除了常规的数组元素之外,返回的数组还含有2个对象属性:index声明匹配文本的起始字符在字符串的位置;input声明对stringObject的引用。
全局调用
若regexp具有标志g则match()将执行全局搜索,找到字符串中的所有匹配子字符串,若未找到任何匹配的字符串,则返回null;若找到了一个或多个匹配字符串,则返回一个数组。
数组元素中存放的是字符串中所有的匹配子串,且也没有index属性或input属性。
String.prototype.split(reg)
常用split()把字符串分割为字符数组:'a,b,c,d'.split(',');//["a","b","c","d"]
复杂的分割情况下也可使用正则表达式解决:'a1b2c3d'.split(/\d/);//["a","b","c","d"]
String.prototype.replace
☞String.prototype.replace(str,replaceStr)
☞String.prototype.replace(reg,replaceStr)
☞String.prototype.replace(reg,function)
function参数含义
function会在每次匹配替换时调用,有4个参数:
1、匹配字符串
2、正则表达式分组内容,没有分组则没有该参数
3、匹配项在字符串中的index
4、原字符串
来源: https://juejin.im/post/5a0ed711f265da431b6cc8b3