正则表达式
date
Oct 11, 2020
slug
zhengze
status
Published
tags
其它
summary
正则表达式
type
Post
字符串是编程时涉及到的最多的一种数据结构,对字符串进行操作的需求几乎无处不在。比如判断一个字符串是否是合法的Email地址,虽然可以编程提取
@
前后的子串,再分别判断是否是单词和域名,但这样做不但麻烦,而且代码难以复用。正则表达式是一种用来匹配字符串的强有力的武器。它的设计思想是用一种描述性的语言来给字符串定义一个规则,凡是符合规则的字符串,我们就认为它“匹配”了,否则,该字符串就是不合法的。
基本语法
在正则中, 如果直接给出字符,就是精确匹配。
\d
可以匹配一个数字,\w
可以匹配一个数字或字母所以:'00\d'
可以匹配001
,但无法匹配00A
'\d\d\d'
可以匹配'123'
'\w\w'
可以匹配'js'
.
可以匹配任意字符:'js.'
可以匹配'jsp'
,'jsa'
,'js#'
等
用
*
表示任意个字符(包括0个),用+
表示至少一个字符,用?
表示0或1个字符,用{n}表示n
个字符,用{n,m}
表示n-m
个字符例1:
\d{3}\s\d{3,8}
\d{3}
表示3个数字,如'010'
\s
表示一个空格
\d{3,8}
表示3-8个数字,如'123'
'10000000'
进阶
要做更精确的匹配,使用
[]
表示范围:[0-9a-zA-Z\_]
匹配一个数字、字母或下划线
[0-9a-zA-Z\_]+
匹配至少由一个数字、字母或下划线组成的字符串,如'a00'
,'KABA_12'
,'1234'
等
[a-zA-Z\_\$][0-9a-zA-Z\_\$]*
匹配字母数字下划线$开头,后接任意长度字符串
[a-zA-Z\_\$][0-9a-zA-Z\_\$]{0,19}
匹配由字母数字下划线$开头后接0-19长度的字符串
[A|B]
匹配A或B,所以:(j|J)ava(s|S)cript
匹配'javascript' 'Javascript' 'javaScript' 'JavaScript'
^
表示行的开头,^\d
表示以数字开头$
表示行的结束,[a-z]$
表示以小写字母结束,+
表示一个或多个RegExp
JS中有两种方式创建一个正则表达式
- 直接通过
/正则表达式/
写出来
- 通过
new RegExp('正则表达式')
创建一个RegExp对象
let reg1 = /ABC\-001/;
let reg2 = new RegExp('ABC\\-001')
reg1; // /ABC\-001/
reg2; // /ABC\-001/ 第二种写法由于字符串的转义,两个\\其实是一个\
判断正则表达式是否匹配
const reg = /^\d{3}\-\d{3,8}$/;
reg.test('010-12345'); //true
reg.test('010-1234x'); //false
reg.test('010 12345'); //false
切分字符串
普通的spilit:
'a b c'.split(' '); // ['a', 'b', '', '', 'c']
无法识别连续空格,使用正则:
'a b c'.split(/\s+/); // ['a', 'b', 'c']
'a,b, c d'.split(/[\s\,]+/); // ['a', 'b', 'c', 'd']
'a,b;; c d'.split(/[\s\,\;]+/); // ['a', 'b', 'c', 'd']
分组
出了判断匹配外,正则还有提取子串的功能,用
()
表示的就是要提取的组:^(\d{3})-(\d{3,8})$
定义了两个组const reg = /^(\d{3})-(\d{3,8})$/
reg.exec('010-12345'); // ['010-12345', '010', '12345']
reg.exec('010 12345'); // null
exec()
方法在匹配成功后,会返回一个Array
,第一个元素是正则表达式匹配到的整个字符串,后面的字符串表示匹配成功的子串。失败返回null
贪婪匹配
正则匹配默认是贪婪匹配,也就是匹配尽可能多的字符:
var reg = /^(\d+)(0*)$/;
reg.exec('102300'); // ['102300', '102300', '']
由于
\d+
采用贪婪匹配,直接把后面的0
全部匹配了,结果0*
只能匹配空字符串了。必须让
\d+
采用非贪婪匹配(也就是尽可能少匹配),才能把后面的0
匹配出来,加个?
就可以让\d+
采用非贪婪匹配:var re = /^(\d+?)(0*)$/;
re.exec('102300'); // ['102300', '1023', '00']