var res = '12345678'.replace(/(?=(\d{3})+$)/g, ',')
console.log(res); // "12,345,678"
var res = '123456789'.replace(/(?!^)(?=(\d{3})+$)/g, ',')
console.log(res); // "123,456,789"
var regex = /(\d{4})-(\d{2})-(\d{2})/;
var string = "2017-06-12";
var result = string.replace(regex, "$2/$3/$1");
console.log(result);
// => "06/12/2017"
正则表达式是一种查找以及字符串替换操作。简单点说就是按照某种规则去匹配符合条件的字符串,正则表达式就是这个规则。
正则表达式是匹配模式,要么匹配字符,要么匹配位置。请记住这句话。
有两个便捷的正则表达式工具: regexper、regex101
一、几个概念
1.1、定义
JavaScript
通过内置对象RegExp
支持正则表达式,提供了两种方式来定义正则表达式规则:JavaScript
字面量(literal)。1.2、 模式修饰符
global
全文搜索, 不添加,搜索到第一个匹配停止ignore case
忽略大小写,默认大小写敏感multiple lines
多行搜索1.3、 元字符 Metacharacter
正则表达式由两种基本字符类型组成
1.4、两种模糊匹配
1.4.1、横向模糊匹配
横向模糊指的是,一个正则可匹配的字符串的长度不是固定的,可以是多种情况的。其实现的方式是使用量词。譬如
{m,n}
,表示连续出现最少m
次,最多n
次。 比如/ab{2,5}c/
表示匹配这样一个字符串:第一个字符是a
,接下来是2到5个字符b
,最后是字符c
。在 regexper 上跑一把看看1.4.2、纵向模糊匹配
纵向模糊指的是,一个正则匹配的字符串,具体到某一位字符时,它可以不是某个确定的字符,可以有多种可能。其实现的方式是使用字符类。譬如
[abc]
,表示该字符是可以字符a
、b
、c
中的任何一个。比如/a[123]b/
可以匹配如下三种字符串:a1b
、a2b
、a3b
。在 regexper 上跑一把看看二、字符类和范围类
2.1、 字符类
用
[]
来构建一个简单的类。 字符类具有“或”的含义,所谓类是指符合某些特征的对象,一个泛指而不是一个特指。比如:表达式
c[abc]t
, 把字母a
、b
、c
归为一类,表达式可以匹配这类中的一个字符。再比如:表达式
c[abc]t
, 表示可以匹配的字符串是以c
开头,接着是abc
中的任何一个字符,最后以t
结尾“。在文本的实际应用中,这样的正则表达式可以匹配:cat
,cbt
,cct
三种字符串。在字符类中,字符的重复和出现顺序并不重要,如
[cbbcaa]
与[abc]
是相同的。2.2、字符类取反,
^
(脱字符)例如
[^abc]
,表示是一个除a
、b
、c
之外的任意一个字符。字符组的第一位放^
(脱字符),表示求反的概念。2.3、范围类
-
单个中横杠在[]
内部表示范围的意思。如果要匹配 - ,可以直接加载后面。比如:使用字符类匹配数字则为
[0123456789]
这样比较麻烦,使用[0-9]
简写,表示任意数字.2.4、预定义类
预定义字符类简称预定义类,正则表达式提供预定义类来匹配常见的字符类,有了这些预定义类,我们写一些正则就简便多了。
.zf
,表示匹配 zf字符串前除回车换行以外的任意单个字符匹配任意字符:[\d\D], [\w\W], [\s\S], [^] 这四个中的任意个都可以
三、量词
量词也称重复,在字符或字符集之后,使用
{}
大括号标识重复, 格式为:{m,n}
a\{2\}
标识匹配字符串a{2}
a{3}
,表示匹配字符串aaa
[{}]
表示匹配一个左边的大括号,或者一个右边的大括号。[abc]{2}
, 不是先匹配a
或b
或c
, 再匹配a
或b
或c
,也就是说[ab]并不表示匹配“aa或bb或cc”3.1、量词的简写
{0,1}
,比如colou?r
表示匹配colour
或color
3.2、贪婪匹配和非贪婪匹配
?
*
+
{n, m}
都是尽可能多的去匹配?
即为非贪婪模式(惰性模式)。提供一个惰性匹配的记忆方式是:量词后面加个问号,问一问你知足了吗,你很贪婪吗?不贪婪,最低要求就够了! 我们在 regex101 试试下面两行代码,然后去体会一下匹配结果。
四、边界字符与位置匹配
常见的边界字符
比如我们把字符串的开头和结尾用"#"替换(位置可以替换成字符的!):
多行匹配模式时,二者是行的概念,这个需要我们的注意:
对于位置的理解,我们可以理解成空字符"",比如"hello"字符串等价于如下的形式:
数字的千分位表示法
五、分支与分组
5.1、分支
多选分支,也叫选择匹配,使用
|
来分割可以匹配的不同选择abc|def
表示匹配abc
或def
abc|def|
,abc||def
,|abc|def
, 这三种情况都表示匹配abc
或def
或一个空字符串。[abc|def]
表示匹配a
或b
或c
或|
或d
或e
或f
a|b|c
与[abc]
相同5.2、分组
使用括号
()
表示分组来匹配一组符号,我们知道
/a+/
匹配连续出现的a
,而要匹配连续出现的ab
时,需要使用/(ab)+/
。其中圆括号是提供分组功能,使量词+
作用于ab
这个整体,str
连续出现3次的场景,错误写法str{3}
,量词只能作用于紧挨着他的字符。正确写法(str){3}
, 量词作用于分组。(Mon|Tues|Wednes|Thurs|Fri|Satur|Sun)day
匹配一周中的某一天[()]
表示匹配任意一个左括号或一个右括号(abc|def)
,如同编程中的分支。(|abc|def)
,注意前面有一个空格, 表示匹配abc
或def
或一个空字符串,即分组可以包括空字符串abc()def
与abcdef
相同(abc|def)?
与(abc|def|)
相同。六、捕获
捕获是
()
的一个非常重要用途,有了它,我们就可以进行数据提取,以及更强大的替换操作。(\w*)ility
, 表示匹配以ility
结尾的词。第一个被捕获的部分是由\w*
控制的,比如输入的文本内容中有单词accessibility
,那么首先被捕获的部分是accessib
,如果输入的文本中有单独的ility
, 则首先被捕获的是一个空字符串。捕获组从左向右编号,也就是只需要对左括号计数。如
(\w+) had a ((\w+) \w+)
, 输入的内容是I had a nice day
I had a nice day
I
nice day
nice
.在其他的一些正则表达式的
API
实现中,可能是从铺获组1开始编号的。6.1、提取数据
如提取出年、月、日,可以这么做:
也可以使用构造函数的全局属性
$1
至$9
来获取:6.2、提取
想把
yyyy-mm-dd
格式,替换成mm/dd/yyyy
怎么做6.3、非捕获分组
前面的分组都会捕获它们匹配到的数据,以便后续引用,因此也称他们是捕获型分组。 如果只想要括号最原始的功能,但不会引用它,此时可以使用非捕获分组
(?:p)
提取年份,在
6.1
的基础上七、案例
7.1、从
html
代码中提取img
的src
地址7.2、隐藏手机号码中间四位
Reference