前端基础之正则表达式

几种用法的区别

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这个字符串只有一个开始的引号,没有结束的引号了。
所以语法报错。

相关推荐