乐趣区

一分钟复习正则

在平时的工作中经常会碰到正则,然而我发现,每次都遗记该怎么去写,所以在这里略微温习总结一下

先看题

/* 题目一 */
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())
// 写出运行后果

看完这三个题目,你是否有想法,上面颁布答案

// 题目一
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 个字符, 例匹配 colorcolour 这两个单词, 就能够写为 /colou?r/
  • 元字符 * 用来示意匹配 0 个字符或无数个字符, 例匹配 colorcolouuuuuur 就能够写为 /colou*r/
  • 元字符 + 实用于要匹配同个字符呈现 1 次或屡次的状况。colorcolour 这两个单词,若应用 /colou+r/ 来匹配,就只能匹配到colour
  • 匹配特定的次数,能够应用元字符 {} 用来给反复匹配设置准确的区间范畴。如 a 我想匹配 3 次, 那么我就应用 /a{3}/ 这个正则,或者说 a 我想匹配至多两次就是用 /a{2,}/ 这个正则。

    • {x}: x 次
    • {min, max}:介于 min 次到 max 次之间
    • {min,}: 至多 min 次
    • {0, max}:至少 max 次

总结
| 匹配规定 | 元字符 |
| :—–:| :—-: |
| 0 次或 1 次 | ? |
| 0 次或无数次 | * |
| 1 次或无数次 | + |
| 特定次数 | {x}, {min, max} |

地位边界

  • 单词边界 \b , 例 The cat scattered his food all over the room. 匹配出所有的单词cat,就能够写成 /\bcat\b/g
  • 字符串边界,元字符 ^ 用来匹配字符串的结尾。而元字符$ 用来匹配字符串的开端。

边界总结:

边界和标记 正则表达式 记忆形式
单词边界 b boundary
非单词边界 B not boundary
字符串结尾 ^
字符串结尾 $
多行模式 m 标记 multiple of lines
疏忽大小写 i 标记 ignore case, case-insensitive
全局模式 g 标记 global

子表达式

分组

所有以 () 元字符所蕴含的正则表达式被分为一组,每一个分组都是一个 子表达式,它也是形成高级正则表达式的根底。

回溯援用

回溯援用(backreference)指的是前面局部援用后面曾经匹配到的子字符串。你能够把它设想成是变量,回溯援用的语法像\1 , \2,…., 其中 \1 示意援用的第一个子表达式,\2 示意援用的第二个子表达式,以此类推。而 \0 则示意整个表达式。

// 例如
// 匹配上面字符串中两个间断的单词
// 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 … 来援用要被替换的字符串

var str = 'abc abc 123';
str.replace(/(ab)c/g,'$1g');
// 失去后果 'abg abg 123'

如果咱们不想子表达式被援用,能够应用非捕捉正则 (?:regex) 这样就能够避免浪费内存。

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)/ 来匹配, 就能够匹配到单词 happilyhapp前缀。如果我想过滤所有以 happ 结尾的副词,那么也能够采纳 负前向查找 的正则 /happ(?!ily)/,就会匹配到happy 单词的 happ 前缀。

后向查找

后向查找 (lookbehind) 是通过指定一个子表达式,而后从合乎这个子表达式的地位登程开始查找合乎规定的字串。举个简略的例子:applepeople 都蕴含 ple 这个后缀,那么如果我只想找到 appleple,该怎么做呢?咱们能够通过限度 app 这个前缀,就能惟一确定 ple 这个单词了。

var str4 = 'apple people';
console.log(str4.replace(/(?<=ap)ple/,'-'))
// 失去后果 'ap- people'
// 阐明匹配到的是单词 apple 的 ple

(?<=regex) 的语法就是 后向查找 regex 指代的子表达式会作为限度项进行匹配,匹配到这个子表达式后,就会持续向后查找。另外一种限度匹配是利用(?<!regex) 语法,这里称为 负后向查找。与正前向查找不同的是,被指定的子表达式不能被匹配到。于是,在下面的例子中,如果想要查找 appleple 也能够写成/(?<!peo)ple

总结
| 回溯查找 | 正则 |
| :—–:| :—-: |
| 援用 | 0,1,2 和 $0, $1, $2 |
| 非捕捉组 | (?:) |
| 前向查找 | (?=) |
| 前向负查找 | (?!) |
| 后向查找 | (?<=) |
| 后向负查找 | (?<!) |

逻辑解决

  • 在正则外面,默认的正则规定都是 的关系
  • [] 外部应用的 ^ 示意非的关系
  • 子表达式匹配的非关系就要用到后面介绍的前向负查找子表达式 (?!regex) 或后向负查找子表达式(?<!regex)
  • 或关系,通常给子表达式进行归类应用。比方,我同时匹配 a,b 两种状况就能够应用 (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代表的是匹配到的大写字母

参考:正则表达式不要背

退出移动版