前端基础之正则表达式
几种用法的区别
1、 match、replace
2、 test
3、 exec
1、match、replace的调用对象是字符串, test,exec的调用对象是正则表达式对象。 2、test 返回结果是boolen值, exec返回的结果是匹配到的数组(没有匹配到返回null) exec执行时,如果没有子匹配项(即没有括号的情况),无论有没有参数g, 只返回一个匹配项, 加g与不加g的区别: 加g再下一次调用exec的时候,会从上一次匹配结束后的地方重新开始匹配(即lastIndex的值会变化), 不加g,每次都是从头开始匹配。 3、match 执行的结果接近 exec。 区别如下: * 当没有子匹配项, 且非全局匹配时, 结果一样 * 当没有子匹配项, 且全局匹配时, 结果不一样,match匹配所有项, 但是exec会从上一次匹配结束后的地方重新开始匹配(即lastIndex的值会变化) * 当有子匹配项, 且非全局匹配时, 结果一样 * 当有子匹配项, 且全局匹配时, 结果不一样, match会忽略子匹配项, exec正确返回所有匹配到的结果。 结论: exec没有子匹配项的时候,只会返回第一个匹配到的数组。 match在有子匹配项后,会匹配所有匹配项,不需要另外添加全局匹配,添加了反倒是不对了。
关于match与exec的区别的例子可以参考这里
replace深入理解
1、replace的调用对象是string;
2、两个参数,
-第一个参数传入的正则表达式(匹配规则);
- 第二个参数是:通过匹配规则匹配到后,想传入的字符串或者函数;
3、返回的是匹配后的字符串。
参考的原文地址:https://www.jianshu.com/p/31b...
一个简单的例子:
var str = 'red+green+world'; str.replace(/red/, blue); // 将通过正则表达式匹配到的结果以第2个参数替换 str.replace(/\+/g, ' '); // 将所有的加号,以空格替换
关于第一个参数,正则表达式没什么可说的,
第2个参数,有点讲究:
$& 第一个参数(规则)的结果 $` 第一个参数(规则)的结果的所有左边的字符串 $' 第一个参数(规则)的结果的所有右边的字符串 $1,$2,$3...$n 第一个参数(规则)的结果的对应的子字符串
$&
$& 适用于没有子表达式的情况
var sStr='讨论一下正则表达式中的replace的用法'; sStr.replace(/正则表达式/,'《$&》'); // 得到:"讨论一下《正则表达式》中的replace的用法"
$`
var sStr='讨论一下正则表达式中的replace的用法'; sStr.replace(/正则表达式/,'《$`》'); // 得到:"讨论一下《讨论一下》中的replace的用法"
$'
匹配字符串右边的所有字符,注意,既然 $' 有单引号,那么外面的引号必须双引号,如果不可以双引号,只能把 $' 的单引号转义。
var sStr='讨论一下正则表达式中的replace的用法'; sStr.replace(/正则表达式/,"《$'》"); // 得到:"讨论一下《中的replace的用法》中的replace的用法"
$1, $2, $3, …, $n
依次匹配子表达式,$1匹配的是字符串中匹配到的内容,不是正则表达式。
全局匹配的情况没写,
@@...@@'markdown语法变成'<blink>...</blink> var a = '@@aaa@@ @@bbb@@'; a.replace(/\"([^"]*)"/g,'<blink>$1</blink>');
var sStr='讨论一下正则表达式中的replace的用法'; sStr.replace(/(正则)(.+?)(式)/,"《$1》$2<$3>"); // 得到:"讨论一下《正则》表达<式>中的replace的用法"
如果第2个参数是函数
先看arguments的用法:
var sStr='讨论一下正则表达式中的replace的用法'; sStr.replace(/(正则).+?(式)/,function() { console.log(arguments); }); // ["正则表达式", "正则", "式", 4, "讨论一下正则表达式中的replace的用法"]
参数分别为:
- 匹配到的字符串(此例为"正则表达式")
- 如果正则使用了分组匹配就为多个否则无此参数。(此例的参数就分别为 "正则", "式")
- 匹配字符串的对应索引位置(也就是"正则表达式"的索引位置,此例为4)
- 原始字符串
正则表达式参数
g全局匹配,i忽略大小写 不带g的情况下,从左向右匹配,如果匹配到了则不在向右匹配了, 带g的情况,则从头到尾都匹配完,返回所有匹配到的数据。
元字符
16个元字符
元字符 名称 匹配对象 . 点号 单个任意字符(除回车\r、换行\n、行分隔符\u2028和段分隔符\u2029外) [] 字符组 列出的任意一个字符 [^] 排除型字符组 未列出的单个任意字符 ? 问号 匹配0次或1次 * 星号 匹配0交或多次 + 加号 匹配1次或多次 {min,max} 区间量词 匹配至少min次,最多max次 ^ 脱字符 行的起始位置 $ 美元符 行的结束位置 | 竖线 分隔两边的任意一个表达式 () 括号 限制多选结构的范围,标注量词作用的元素,为反向引用捕获文本 \1,\2... 反向引用 匹配之前的第一、第二...组括号内的表达式匹配的文本 \w 匹配字母或数字或下划线或汉字 \d 匹配数字 \b 匹配单词的开始或结束 \s 匹配任意的空白符
特殊分组匹配(只匹配不捕获)
(?:exp)
匹配exp,不捕获,不分组
位置匹配(零宽断言)
(exp)
匹配exp,并且分组
1,匹配某个字符串前面的位置(?<=exp)
这个位置的前面能匹配exp(这个位置的前面是exp)
2,匹配exp后面的位置(?=exp)
这个位置的后面能匹配exp(这个位置的后面是exp)
3,匹配某个字符串前面的位置(?<!exp)
这个位置的前面不能匹配exp(这个位置的前面不是exp)
4,匹配exp后面的位置(?!exp)
这个位置的后面不能匹配exp(这个位置的后面不是exp)
关于零宽断言的一个例子
匹配三个字符img的随机组合,但是不能重复var reg = /i|m|g|im|mi|ig|gi|mg|gm|img|igm|mig|mgi|gim|gmi/
;
上面这种写法确实可以。
/^(?!([img])(?=.*\1))[img]+$/
上面的正则表达式在正则铁路图中看的更清楚。
正则铁路图
理解:?!
这个位置的后面,不能满足表达式([img])(?=.*\1)
,才可以。
这个比较绕, ?=
,用它来理解, 这个位置的后面,需要满足表达式([img])(?=.*\1)
,才可以。
这个表达式是([img])(?=.*\1)
;
先是匹配img其中一个,紧跟着的后面的字符串中需要满足\1
,即是之前匹配成功后的img其中一个。([img])(?=.*\1)
的意思也就是说, 必须重复出现i*i
,m*m
,g*g
这种情况,才满足。
然后?!
,取反,不能重复出现i*i
,m*m
,g*g
这种情况,才满足。
也就是说,在开始位置,不能重复出现i*i
,m*m
,g*g
这种情况。/^(?!([img])(?=.*\1))[img]+$/
,不能满足igg,能后面重复的情况。
/^(([img])(?!.*\2))+$/
的理解:
通过正则铁路图理解([img])(?!.*\2)
先是匹配img其中一个,紧跟着的后面的位置,后面的子符串中不能有\2
,即是之前匹配成功后的img其中一个。然后整体向后循环检验不能出现重复字符。
split
split是根据指定的分隔符,将字符串分隔成多个子字符串,返回这些子字符串构成的数组。
split中使用正则来实现分割。
var colorText = "red,blue,green,yellow"; var colors3 = colorText.split(/[^\,]+/); //["", ",", ",", ",", ""]
/[^\,]+/
这个正则表达式的意思就是,不是,
的多个字符。
也就是说根据不是,
的多个字符,将colorText
分割。
不是,
的多个字符 指的就是red blue green yellow,
分割结果就是:'' (red) ',' (blue) ',' (green) ',' (yellow) ''
括弧中的就是指定的分割符,结果就是["", ",", ",", ",", ""]
。
转译
js中申明:
var str = '1/';
会报错,
但是
var str = '1\';
不会报错,为什么呢?\
这个东东是可以转译其他特殊字符的,看下面这个,
var str = '1\'';
当这么申明后, var str = '1\''
; \
后面的单引号被\
给转译成了一个普通的引号,就成了 var str = '1''
,
如果写成var str = '1\', 由于
`后面的单引号被\
给转译成了一个普通的引号了, str这个字符串只有一个开始的引号,没有结束的引号了。
所以语法报错。