首先大家可以打开下面 的工具来进行正则的实操练习。
PHP, PCRE, Python, Golang and JavaScriptregex101.com引言:正则本质上无非是匹配对的字符和匹配对的位置。
匹配字符
- 在javascript中,正则表达式可以以两种方式创建。
var regex = new RegExp(regex,flag)
var pattern = /regex/flag
例如:
var pattern = /s/g
var reg = new RegExp("s","g")
以上两种正则都可以匹配所有空白符,s
在正则里表示空白符tvnrf
。
个人比较推荐第一种写法,因为第二种需要用反斜杠对反斜杠进行转译,比较容易造成歧义。
2. 直接匹配:直接输入需要匹配的字段,通过flag修饰符来控制筛选条件。flag是斜杠后面的修饰符,可以单个也多个一起出现。比如g
代表global
,表示全局匹配,i
代表case-insensitive
,表示忽略大小写。空格在正则中不会被忽略,请谨慎使用。
例1:忽略大小写
var pattern = /I like playing Warcraft/i
这个正则忽略了大小写,所以不管是i like playing warcraft
或者I LIke PlaYing WARcraft
都会被匹配到。(是不是很简单粗暴呢)
例2:全局匹配
var pattern = /生活/
var pattern =/生活/g
3. 正则表达式中的字符组,对一个字符位进行匹配筛选。
在正则中,方括号[]
之间的位置可以自动行使'或'的功能。
例如:/[江河湖海]南/g
可以匹配字符串中出现的江南、河南、湖南、海南,但无法匹配越南。
- 字符组内可以使用脱字符
^
来求反
例如:[^cdm]ash
cash dash mash 都不会被匹配 hash可以被成功匹配
注:脱字符在组中表示开头。
- 字符组中可以用范围来表示适用字符的范围
例如:
[abcdefghijk]=>[a-k]
[0123456789]=>[0-9]
[0123456789abcdef]=>[0-9a-f]
- 常用的简写
虽然可以用-
表示范围,但工程师的懒惰是止不住的,所以还有更进一步的常用简写。
a. d
表示匹配数字,等同于[0-9]
。
b. D
表示匹配数字之外的任何字符,等同于[^0-9]
,也就是d
取反。
c. w
表示匹配所有字母,数字和下划线,等同于[a-zA-Z0-9_]
。
d. W
表示匹配非单词字符,等同于[^a-zA-Z0-9_]
,也就是w
取反。
e. s
表示空白符,等同于[tvnrf]
。
f. S
同理,S
表示s
的取反。
g. .
点字符可以代表任何单个字符。
4. 正则表达式中的量词,表示对一个规则在数量上的延伸。
例如:/d{3}/
匹配连续的3位数字 。
例如:/d{3,5}/
匹配连续3到5位的数字。
例如:/d{3,}/
匹配3位以上的连续数字。
例如:/d+/
匹配3位以上的连续数字 +
等同于{1,}
。
*
表示0个及以上,等同于{0,}
。
?
表示该规则可以存在0次或者1次,等同于{0,1}
。
5. 正则表达式中的组:由括号()
包裹的区域表示一个组,组表示一个独立的规则区域。
例如:(abc|cde){2,3}
表示匹配abc或者cde重复两到三遍的字符串。
组是一个独立的匹配单元。比如匹配小时,分钟的时候就可以对规则进行拆分,从而提取到颗粒度更高的数据。
思考题
练习1:
匹配16位进制颜色码
,颜色码以#
号开头,由3
位或6
位16
进制的字符组成,每个字符范围0-9
合并a-f
。
测试用例: #000 #abc #0023AB #0Ab #FFFFFD
答案:#([0-9a-f]{3}){1,2}
练习2:匹配时间24小时制。
测试用例:23:59 03:02 07:00 12:00
答案:([0-1]d|2[0-3]):([0-5]d)
匹配位置
- 正则表达式的锚点
除了匹配字符,正则表达式也具有匹配位置(锚点)的功能。
简而言之:位置就是见缝插针。
^
脱字符匹配开头
str.replace(/^/,'开头') //开头str
$
匹配结尾
str.replace(/$/,'结尾') //str结尾
b
匹配w
与W
之间,w
与^
之间,w
与$
之间的空隙 (这个规则和下面的规则看一下就好)B
匹配与b
意思相反取得是W
与W
之间、w
与w
之间、W
与^
之间,W
与$
之间的空隙。
2. 先行断言 (positive lookahead)
先行断言表示判断某位置之前是不是合规,通俗的讲就是判断张三前面是不是坐着李四,人民币符号¥
前面是不是跟着数字。它基本的表示方法就是(?=规则)
。
reg)(?=¥)
匹配¥
之前符合要求的字段,请看下面的例子
我是 :/d+(?=¥)/
表示匹配¥
前面的的数字
同样,先行断言也可以取反,格式就是(?!规则)
。比如,(?!¥)
表示符合规则的字符串不可以出现在¥
之前。
3. 后行断言 (positive lookbehind)
与前行断言类似,后行断言表示判断某位置之后是不是合规。需要注意的是,后行断言是ES6的新特性,要考虑兼容。在Taro2.0.4小程序的开发中会报错(Taro团队,假如你们看到话,请修复一下)。
比如,(?<=$)(reg)
可以匹配$之后的数字,因为$
本身在正则中表示结尾,所以用了反斜杠转译。
后行断言也可以取反,将=
替换成!
即可。例如,(?<!$)(reg)
表示匹配不在$
后面的规则。
参考文章:
JS正则表达式完整教程(略长) - 掘金juejin.im