-
正则表达式
学习基础的正则 处理过程。核心的概念理解
-
单个字符
正则 含义 Dome . 所有 换行符除外 \n 换行 \f 换页 \r 回车 \t 制表符 Tab \v 垂直制表符 a,b,…z 标识英文字母 0,1,2,9 数字 “\” 修改下一个字符串的含义 “\*” 匹配"*" 而不是所有 -
转义字符
^ $ . * + ? | \ / ( ) [ ] { } = ! : - , 匹配时 需要\进行转义
-
多个字符
正则 含义 [0-9] \d 标识数字 [^0-9] \D 非数字 [a-zA-Z0-9_] \w word 所有单词组成 [^a-zA-Z0-9_] \W 非word \s \t\v\n\r\f \S ^\t\v\n\r\f -
逻辑
正则 含义 Dome 无 与关系 [^regex]或 ! 非 “|” 或 (\d)|(\w) -
边界
-
单词边界 \b [\w和\W之间]
-
\B
含义 Dome [\w和\W之间] 单词字符 和不能构成单词字符 中间的位置 可以表示[空字符串[" "], 字符串头 字符串尾 . _ =所有(转义字符) ] 和\b相反 便是\w[]\W \w[]\w \W[]\W之间 的位置 "hello ASS9090sa aaa" "[]hello[] []ASS9090sa[] []aaa[]" the cat scatterrd his food all over the room /cat/ => cat scatterrd /\bcat\b/ ==>cat
-
字符串边界 ^ $
含义 Dome 符串开头 1+ 符串结尾 [a-z]$ "hello".replace(/^|$/g, '#') = #hello#
-
-
正向查找 反向查找
操作符 说明 描述 (?=exp) 正向前查找 匹配exp前面的位置 (?<=exp) 正向后查找 匹配exp后面的位置 (?!exp) 负 向前查找 [你找的]不能在reg前面 (?< !exp) 负 向后查找 [你找的]不能在reg后面 -
负 向前查找
"apple appAA" 向前查找:查找app 希望紧跟后面紧跟le /(app)(?=(le))/ ==> index=0 负向前查找:查找app 希望紧跟后面不是le /(app)(?!(le))/ ==> index=6
-
-
循环与重复 [多次匹配]
正则 含义 Dome 出现0或者1次 [z-a]{0,1} 用于匹配可有可无 {0,} 1次或多次 {1,} 9} 出现九次 1,9} 出现一次到九次 8,} 至少出现8次 -
贪婪匹配和惰性匹配
-
贪婪匹配
var regex = /\d{2,5}/g; var string = "123 1234 12345 123456"; console.log( string.match(regex) ); // => ["123", "1234", "12345", "12345"] 默认为贪婪匹配 他会尽可能多的匹配
-
惰性匹配 [加个问号就能实现惰性匹配]
{m,n}? {m,}? ?? +? *?
-
-
分组
-
如何分组 ()
let str = "2019-12-21"; /^(\d{4})-(\d{2})-(\d{2})/g.exec(str) ["2019-12-21", "2019", "12", "21", index: 0, input: "2019-12-21", groups: undefined]
-
非捕捉分组
- ()分组匹配的值 会被保存 $n来读取
- (?:)表示非捕捉分组 值不会被保存 不会被$保存
-
组的引用
-
值的引用 $1-$9
let str = "2019-12-21"; /^(\d{4})-(\d{2})-(\d{2})/g.exec(str) //["2019-12-21", "2019", "12", "21", index: 0, input: "2019-12-21", groups: undefined] (RegExp.$1) == 2019 (RegExp.$2) == 12 (RegExp.$3) == 21
let str = "2019-12-21"; str.replace(/^(\d{4})-(\d{2})-(\d{2})/g,function(a,b,c,d){ 参数为 RegExpExecArray的展开值 return RegExp.$2 + "/" + RegExp.$3 + " " + RegExp.$1; return "$2/$3 $1" })}) str.replace(/^(\d{4})-(\d{2})-(\d{2})/g, "$2/$3 $1")
-
正则反向引用 [ \1 \2 ] 引用之前组的结果
str1 = "2019/01/02" 可以匹配 str2 = "2019-02-23" 可以匹配 str3 = "2019/5-05" 不可匹配 思路:对分割符进行分组 之后的引用该分组结果 /^(\d{4})(.)(\d{2})\2(\d{2})/g \2 直接 之前(/.)组的结果
-
组的嵌套 以左括号”(“为准
var regex = /^((\d)(\d(\d)))\1\2\3\4$/; var string = "1231231233"; regex.test(string) \1,是第一个分组内容,那么看第一个开括号对应的分组是什么,是123, \2,找到第2个开括号,对应的分组,匹配的内容是1, \3,找到第3个开括号,对应的分组,匹配的内容是23, \4,找到第3个开括号,对应的分组,匹配的内容是3。
-
-
-
回溯法
简单总结就是,正因为有多种可能,所以要一个一个试。直到,要么到某一步时,整体匹配成功了;要么最后都试完后,发现整体匹配不成功。
- 贪婪量词“试”的策略是:买衣服砍价。价钱太高了,便宜点,不行,再便宜点。
- 惰性量词“试”的策略是:卖东西加价。给少了,再多给点行不,还有点少啊,再给点。
- 分支结构“试”的策略是:货比三家。这家不行,换一家吧,还不行,再换。
-
正则表达式 规则 正则过程解析
-
结构
- 字面量,匹配一个具体字符,包括不用转义的和需要转义的
- 字符组,匹配一个字符,可以是多种可能之一,比如[0-9]
- 量词,表示一个字符连续出现,比如a{1,3}
- 锚点,匹配一个位置,而不是字符 ^ $ \b \B 4个正向反向查找。
- 分组,用括号表示一个整体 ()
- 分支,多个子表达式多选一 reg | ds
- 反向引用,比如\2
-
操作符 【操作符的优先级从上至下,由高到低】
- .转义符 \
- .括号和方括号 (…)、(?:…)、(?=…)、(?!..)、[…]
- .量词限定符 {m}、{m,n}、{m,}、?、*、+
- 位置和序列 ^ 、$、 \元字符、 一般字符
- 管道符(竖杠)|
匹配目标字符串"abc"或者"bcd"时 /^abc|bcd$/g X 位置字符和字符序列优先级要比竖杠高 /^(abc|bcd)$/g √
-
修饰符
-
g 全局匹配,即找到所有匹配的,单词是global
-
i 忽略字母大小写,单词ingoreCase
-
m 多行匹配,只影响^和$,二者变成行的概念,即行开头和行结尾。单词是multiline
-
-
-
正则四种操作 API讲解 (前提是匹配查找)
-
验证、
-
切分、
-
提取、
-
替换
1:验证 test | match seach | 2:切分 "2019-1-1".split("-") "2019-1-1".split(/\D/)
String#search String#split String#match String#replace RegExp#test RegExp#exec 字符串的四个方法都支持正则表达式
-
search match会把字符串转为正则
"100.00".search(".") 得到0 匹配到1 (.) "100.00".search("\\.") 得到3 匹配到.
-
match 返回的结果和/g有关
var string = "2017.06.27"; var regex1 = /\b(\d+)\b/; var regex2 = /\b(\d+)\b/g; // => ["2017", "2017", index: 0, input: "2017.06.27"] // => ["2017", "06", "27"] 没有g ==>标准匹配格式 数组的第一个元素是整体匹配的内容, 接下来是分组捕获的内容, 然后是整体匹配的第一个下标, 最后是输入的目标字符串。 有g 返回的是所有匹配的内容 当没有匹配时,不管有无g,都返回null。
-
exec 相比 match
-
match
- match 没有g时,使用match返回的信息比较多
- match 但是有g后,就没有关键的信息index了
-
exec
- 能接着上一次匹配后继续匹配 lastIndex表示下一次开始匹配的位置
let str = "2019-11-11" let reg = /\b(\d+)\b/g reg.lastIndex == 0 reg.exec(str) ==>["2017", "2017", index: 0, input: "2017.06.27"] reg.lastIndex == 4 reg.exec(str) ==>["06", "06", index: 5, input: "2017.06.27"] reg.lastIndex == 7 循环解决 var string = "2017.06.27"; var regex2 = /\b(\d+)\b/g; var result; while ( result = regex2.exec(string) ) { console.log( result, regex2.lastIndex ); }
-
RegExp
- /(\d{3})+\1/g
- 使用构造器 new RegExp("(\d{3})+\1")
- global、ingnoreCase、multiline、当前是什么模式
- lastIndex 下一次匹配的起点
- source 显示当前的正则表达式
-
-
-
-
理解 用例
-
位置。 理解为空字符串。相邻字符之间的位置
-
如何匹配位置 8个锚点符
^ $ \b \B 4个正向反向查找
let str = "hello" l前面加入# 就是在he[]l[]lo 两个位置[空字符串]替换为# str.replace(/(?=l)/g,"#") == "he#l#lo"
let str = "123456789" 每隔三位插入一个"," 变为 "123,345,678" 理解为在123[]456[]789 的位置上吧空字符串变为"," //str.replace(/(?=(\d{3})+$)/g,",") str.replace(/(?!^)(?=(\d{3})+$)/g,",")
let str = "12345678 123456789" "12,345,678 123,456,789" 每三个加入, "12345678\b 123456789\b" \b位置向前查找 "\b12345678 \b123456789" \b位置不能出现 str.replace(/(?!\b)(?=(\d{3})+\b)/g,",")
-
-
a-z ↩︎