在平时的工做中经常会碰到正则,可是我发现,每次都忘记该怎么去写,因此在这里稍微复习总结一下
/* 题目一 */ var str1 = '123456765464153513566' // 分割数字每三个以一个逗号划分(从后往前) // 如1234 -> 1,234 /* 题目二 */ var str2 = "get-element-by-id" // 将-的命名方式改成小驼峰 // 指望结果getElementById /* 题目三 */ var str3 = 'getElementById' console.log(str3.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase()) // 写出运行结果
看完这三个题目,你是否有想法,下面公布答案git
// 题目一 console.log(str1.replace(/(\d)(?=(\d{3})+$)/g,'$1,')) // 123,456,765,464,153,513,566 // 题目二 console.log(str2.replace(/-\w/g, ($0) => { return $0.slice(1).toUpperCase() })) // getElementById // 题目三 // get-element-by-id
若是你的答案所有正确,那么请忽略下面的内容正则表达式
apple
这个单词里找到a
这个字符,就直接用/a/
这个正则就能够了*
,须要使用\
来转义去掉其原本的含义,正则就能够写成/\*/
特殊字符 | 正则表达式 | 记忆方式 |
---|---|---|
换行符 | n | new line |
换页符 | f | form feed |
回车符 | r | return |
空白符 | s | space |
制表符 | t | tab |
垂直制表符 | v | vertical tab |
回退符 | [b] | backspace,之因此使用[]符号是避免和b重复 |
[
和]
,如/[123]/
这个正则就能同时匹配1,2,3三个字符。用/[0-9]/
就能匹配全部的数字, /[a-z]/
则能够匹配全部的英文小写字母匹配区间 | 正则表达式 | 记忆方式 |
---|---|---|
除了换行符以外的任何字符 | . | 句号,除了句子结束符 |
单个数字, [0-9] | d | digit |
除了[0-9] | D | not digit |
包括下划线在内的单个字符,[A-Za-z0-9_] | w | word |
非单字字符 | W | not word |
匹配空白字符,包括空格、制表符、换页符和换行符 | s | space |
匹配非空白字符 | S | not space |
?
表明了匹配一个字符或0个字符, 例匹配 color
和 colour
这两个单词, 就能够写为 /colou?r/
*
用来表示匹配0个字符或无数个字符, 例匹配 color
和colouuuuuur
就能够写为 /colou*r/
color
和colour
这两个单词, 若使用 /colou+r/
来匹配,就只能匹配到colour
匹配特定的次数, 可使用元字符 {
和 }
用来给重复匹配设置精确的区间范围。如 a
我想匹配3次,那么我就使用 /a{3}/
这个正则,或者说 a
我想匹配至少两次就是用 /a{2,}/
这个正则。app
总结
| 匹配规则 | 元字符 |
| :-----:| :----: |
| 0次或1次 | ? |
| 0次或无数次 | * |
| 1次或无数次 | + |
| 特定次数 | {x}, {min, max} |
\b
, 例 The cat scattered his food all over the room.
匹配出全部的单词cat
, 就能够写成 /\bcat\b/g
^
用来匹配字符串的开头。而元字符$
用来匹配字符串的末尾。边界总结:post
边界和标志 | 正则表达式 | 记忆方式 |
---|---|---|
单词边界 | b | boundary |
非单词边界 | B | not boundary |
字符串开头 | ^ | - |
字符串结尾 | $ | - |
多行模式 | m标志 | multiple of lines |
忽略大小写 | i标志 | ignore case, case-insensitive |
全局模式 | g标志 | global |
全部以 (
和 )
元字符所包含的正则表达式被分为一组,每个分组都是一个子表达式
,它也是构成高级正则表达式的基础。spa
回溯引用(backreference)指的是后面部分引用前面已经匹配到的子字符串。你能够把它想象成是变量,回溯引用的语法像\1
, \2
,....,其中 \1
表示引用的第一个子表达式,\2
表示引用的第二个子表达式,以此类推。而 \0
则表示整个表达式。code
// 例如 // 匹配下面字符串中两个连续的单词 // Hello what what is the first thing, and I am am scq000. var str4 = 'Hello what what is the first thing, and I am am scq000.' console.log(str4.match(/\b(\w+)\s\1/g))
用 $1
, $2
...来引用要被替换的字符串orm
var str = 'abc abc 123'; str.replace(/(ab)c/g,'$1g'); // 获得结果 'abg abg 123'
若是咱们不想子表达式被引用,可使用非捕获正则(?:regex)这样就能够避免浪费内存。ip
var str = 'scq000'. str.replace(/(scq00)(?:0)/, '$1,$2') // 返回scq00,$2 // 因为使用了非捕获正则,因此第二个引用没有值,这里直接替换为$2 var str4 = 'scq000 scq001' console.log(str4.replace(/(scq00)(?:0)/, '$1,$2')) // 返回 scq00,$2 scq001
前向查找(lookahead)是用来限制后缀的。凡是以 (?=regex)
包含的子表达式在匹配过程当中都会用来限制前面的表达式的匹配。例如happy
happily
这两个单词,我想得到以 happ
开头的副词,那么就可使用/happ(?=ily)/
来匹配, 就能够匹配到单词happily
的happ
前缀。若是我想过滤全部以 happ
开头的副词,那么也能够采用负前向查找的正则/happ(?!ily)/
,就会匹配到happy
单词的happ
前缀。内存
后向查找(lookbehind)是经过指定一个子表达式,而后从符合这个子表达式的位置出发开始查找符合规则的字串。举个简单的例子: apple
和 people
都包含 ple
这个后缀,那么若是我只想找到 apple
的 ple
,该怎么作呢?咱们能够经过限制app这个前缀,就能惟一肯定 ple
这个单词了。element
var str4 = 'apple people'; console.log(str4.replace(/(?<=ap)ple/,'-')) // 获得结果 'ap- people' // 说明匹配到的是单词apple的ple
(?<=regex)
的语法就是后向查找,regex
指代的子表达式会做为限制项进行匹配,匹配到这个子表达式后,就会继续向后查找。另一种限制匹配是利用(?<!regex)
语法,这里称为负后向查找。与正前向查找不一样的是,被指定的子表达式不能被匹配到。因而,在上面的例子中,若是想要查找 apple
的ple
也能够写成/(?<!peo)ple
总结
| 回溯查找 | 正则 |
| :-----:| :----: |
| 引用 | 0,1,2 和 $0, $1, $2 |
| 非捕获组 | (?:) |
| 前向查找 | (?=) |
| 前向负查找 | (?!) |
| 后向查找 | (?<=) |
| 后向负查找 | (?<!) |
[
和 ]
内部使用的 ^
表示非的关系(?!regex)
或后向负查找子表达式(?<!regex)
(a|b)
这样的子表达式。到这里正则差很少已经复习了一遍,咱们如今再去看前面的三道题
/* 题目一 */ var str1 = '123456765464153513566' // 分割数字每三个以一个逗号划分(从后往前) // 如1234 -> 1,234 console.log(str1.replace(/(\d)(?=(\d{3})+$)/g,'$1,')) // 123,456,765,464,153,513,566
解析:\d
表示单个数字,(?=(\d{3})+$)
是一个前向查找,\d{3})+$
表示匹配3位数字一次或者屡次而且以三位数字结尾。连在一块儿看就是,匹配一个数字,数字后面的数字位数是3的倍数,因此匹配到的数字是3, 6, 5, 4, 3, 3
,而后替换为$1,
,故3
替换为3,
、 6
替换为6,
....
/* 题目二 */ var str2 = "get-element-by-id" // 将-的命名方式改成小驼峰 // 指望结果getElementById console.log(str2.replace(/-\w/g, ($0) => { return $0.slice(1).toUpperCase() }))
解析:首先/-\w/g
的意思是匹配全部前面是-
的单个字符
,匹配的结果是-e, -b, -i
, 而后取其第二位(也就是将-
截取掉),再转换为大写
/* 题目三 */ var str3 = 'getElementById' console.log(str3.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase()) // 写出运行结果 // 答案:get-element-by-id
解析: ([a-z])([A-Z])
的意思就是匹配两个字母,而且第一个是小写,第二个是大写,因此匹配到的结果是tE, tB, yI
,因为()
表明分组,故$1
表明的是匹配到的小写字母,$2
表明的是匹配到的大写字母
参考: 正则表达式不要背