前言
使用正则,可以少写很多的判断,使代码更加的优雅,可以从字符串当中拿出任何你需要的字符,然后进行加工,得到你想要的任何结果,听起来是不是很棒?
然而正则的表达式看起来不是那么的浅显易懂,往往通用的东西都会更加的抽象,只有抽象出来,才能普适.
正文
从创建说起 两种创建方式:
- new RegExp
- / /, (推荐,除非是需要动态创建)
const dynamicReg = 'some_sort_variable'
const test = new RegExp(dynamicReg, 'ig')
const literal1 = /some_sort_variable/ig
const literal2 = /some_sort_variable/ig
console.log(literal1.toString() === test.toString()) // true
console.log(literal1 === literal2) // false,所有的正则都是新的对象
// 用于动态(运行时)创建
function findClassInElement(className, type) {
const elems = document.getElementsByClassNames(type);
const re = new RegExp("(\\s|^)" + className + "(\\s|$)") // <div class='foo bar zoo'></div>
let result = [];
for (let elem in elems) {
if (re.test(elem.className)) {
result.push(elem)
}
}
}
字符集 [ ],表示中括号中的任意一个字符匹配
const test = /[abc]/ // 匹配a或b或c而不是abc
const test2 = /[^abc]/ // 匹配非a非b非c的任意字符
特殊字符
- ^ 开始符
- $ 结束符
- . 匹配任何字符
- ? 匹配0个或1个,用于非贪婪匹配
-
- 匹配一个或多个
-
- 匹配0个,1个或多个
- \ 匹配特殊字符
- () 分组(?:)或捕获
-
或 - \1,\2 back reference, 获取对应位置的匹配值
const re = /<(\w+)[^>]*>(.*)?<\/\1>/ // <div></div>
方法
- test 返回是否满足对应规则
- match
- 本地的match,不带/g,返回所有匹配值和捕获值
- 全局的match,带/g, // 返回所有匹配值(没有捕获值)
const test_string = "I am Lorry" const match1 = test_string.match(/(\w+)\s/) // [ "I ", "I" ] const match2 = test_string.match(/(\w+)\s/g) // [ "I ", "am "]
- exec
- 跟生成器一样,(yield)一个一个的往下匹配
- 包含匹配的值(result[0]),也包含捕获的值(对应序列) ```js const html = “<div class='test'>Helloworld!</div>” const tag = /<(\/?)(\w+)([^>]?))>/g let match, num = 0; while(match = tag.exec(html) !== null) { num ++ console.log(match.length === 4) // 1 find and 3 captured } console.log(num === 6) // 一共匹配了六次 const pattern = /<(\w+)[^>]?>(.*?)<\/\1>/g let match = pattern.exec(‘Hello’) // [“<div class='hello'>Hello</div>”, “div”, “Hello”, index: 0, input: “<div class='hello'>Hello</div>”, groups: undefined]
// 还可以在replace中反向引用捕获值 ‘Hello‘.replace(pattern,”标签内容为:$3”) // 标签内容为: Hello
## ? 的用法
### (?:) 匹配不捕获
### (?=) 前置断言
### (?|) 前置否定断言
```js
/(\w+)\s(?:\d+)%/.exec('process 100%') // 匹配不捕获 ["process 100%", "process", index: 0, input: "process 100%", groups: undefined]
/\d+(?=%)/.exec('100%') // 匹配且捕获 ["100", index: 0, input: "100%", groups: undefined]
/\d+(?!%)/.exec('100/100') // 匹配且捕获["100", index: 0, input: "100/100", groups: undefined]
replace的使用,在结合函数可以很方便的对字符串进行替换和修改
'ABCDefg'.replace(/[A-Z]/g, "X") // "XXXXefg"
'i-am-lorry'.replace(/-(\w)/g, (all,letter) => letter.toUpperCase()) // "iAmLorry"
挑战任务: 将foo=1&foo=2&foo=3&bar=4&bar=5 替换成 foo=1,2,3&bar=4,5
let compress = (resource) => {
const keys = {};
const pattern = /(\w+)\=(\d+)/g;
let match;
while((match = pattern.exec(resource)) !== null) {
if (!keys[match[1]]) {
keys[match[1]] = match[2]
} else {
keys[match[1]] += `,${match[2]}`
}
}
let res = Object.keys(keys).map(key => key + '=' + keys[key])
return(res.join('&'));
}
compress('foo=1&foo=2&foo=3&bar=4&bar=5') // "foo=1,2,3&bar=4,5"