1. 正则对象 RegExp 上的常见属性和方法
1.1 RegExp 的属性
1.1.1 只读属性: RegExp.prototype.global , RegExp.prototype.ignoreCase , RegExp.prototype.multiline
值为 true 或 false, 表示该正则表达式是否使用了对应的修饰符
global描述是否使用g修饰符ignoreCase描述是否使用i修饰符multiline描述是否使用m修饰符
1.1.2 regExpObj.lastIndex(可读可修改)
- 只有存在修饰符
g的时候才起作用(否则无论lastIndex的值是多少, 都默认为0)let reg = /\d+/ reg.lastIndex = 4 console.log(reg.lastIndex) //=> 4 reg.exec("123a456") //=> ["123", index: 0, input: "123a456", groups: undefined] // 即使更改了 lastIndex 的值, 其在匹配的时候依然会从 0 开始 - 表示下一次匹配字符串时, 从字符串开始的下标 ( 无论是否和刚才匹配的是同一个字符串 )
- 当匹配字符串失败时, 其值又会变为
0let reg = /\dabc/g let str = "1abc2abc3abc" console.log(reg.lastIndex) //=> 0 表示下一次匹配从字符串下标为 0 的位置开始 reg.exec(str) //=> ["1abc", index: 0, input: "1abc2abc3abc", groups: undefined] console.log(reg.lastIndex) //=> 4 表示下一次匹配从字符串下标为 4 的位置开始 reg.exec(str) //=> ["2abc", index: 4, input: "1abc2abc3abc", groups: undefined] // 更换正则所匹配的字符串, 依然会从 lastIndex 的位置开始匹配 console.log(reg.lastIndex) //=> 8 表示下一次匹配从字符串下标为 8 的位置开始 reg.exec("0abc12345abc") //=> ["5abc", index: 8, input: "0abc12345abc", groups: undefined]
1.2 RegExp 的方法
1.2.1 RegExp.prototype.test(str)
尝试用正则对象对字符串 str 进行匹配, 若能够匹配则返回 true, 若不能匹配就返回 false
如果正则表达式中有修饰符 g, 则其还有更改 lastIndex 的能力
/\d+/.test("12345") //=> true
/\d+/g.test("abcde") //=> false
let reg = /\d+/g
console.log(reg.lastIndex) //=> 0
reg.test("12abc") //=> true
console.log(reg.lastIndex) //=> 2
1.2.2 RegExp.prototype.exec(str)
尝试用正则表达式对字符串 str 进行匹配, 若不能匹配则返回 null,
若能匹配, 则返回一个数组
- 下标
0: 表示正则表达式的匹配结果 - 下标
1, 2, 3...: 表示捕获所得的结果 - 属性
index: 表示正则表达式所匹配的子字符串在原字符串str中的起始下标 - 属性
input: 表示用于匹配的源字符串str - 属性
groups: 具名捕获组- 最基本的捕获的应该是
(x), 表示捕获匹配正则表达式x规则的字符串 - 但是应用具名捕获组:
(?<name>x), 在捕获了对应字符串的前提下, 还会将捕获的字符串以value的形式存储在key为自主命名为name的groups对象中
- 最基本的捕获的应该是
let reg = /(?<integerPart>\d+)\.(?<decimalPart>\d+)/
let str = "123.456"
let array = reg.exec(str)
console.log(array)
//=> ["123.456", "123", "456",
// index: 0, input: "123.456", groups: {integerPart: "123", decimalPart: "456"}]
/**
* array[0] 为该正则匹配的结果, array[1, 2, 3...] 为分组匹配的结果
* array.index 为正则表达式所匹配的字符串在源字符串中的起始下标
* array.input 为正则表达式所匹配的源字符串
* array.groups 为具名捕获组的对象, 存放了具名捕获的 key-value 键值对
*/
2. String 上的有关正则的常见方法
2.1 String.prototype.match(reg)
- 如果传入的
reg并不是RegExp, 则会将其转换成RegExp - 如果
reg中没有g修饰符, 则其返回值和RegExp.prototype.exec(str)一样 - 如果
reg中含有g修饰符, 则返回所有正则匹配的结果所组成的数组(没有index,input和groups, 也没有捕获所得到的字符串), 无法匹配则返回null
let str = "123.456"
str.match(/\d+/) //=> ["123", index: 0, input: "123.456", groups: undefined]
str.match("\\d+") //=> ["123", index: 0, input: "123.456", groups: undefined]
str.match(/\d+/g) //=> ["123", "456"]
str.match(/(\d+)\.(\d+)/g) //=> ["123.456"]
2.2 String.prototype.matchAll(reg)
弥补了 String.prototype.match(reg) 不能获取捕获内容的缺点
- 如果传入的
reg并不是RegExp, 则会将其转换成RegExp - 如果
reg中没有g修饰符, 则会直接报错
const str = "String.prototype.matchAll(reg)"
const reg = /(\w+)/g
console.log(...str.matchAll(reg))
/* =>
* ["String", "String", index: 0, input: "String.prototype.matchAll(reg)", groups: undefined]
* ["prototype", "prototype", index: 7, input: "String.prototype.matchAll(reg)", groups: undefined]
* ["matchAll", "matchAll", index: 17, input: "String.prototype.matchAll(reg)", groups: undefined]
* ["reg", "reg", index: 26, input: "String.prototype.matchAll(reg)", groups: undefined]
* 每一个数组都相当于是一次 reg.exec(str) 的结果
*/
2.3 String.prototype.replace(reg|subStr, newSubStr|callbackFn)(并不改变源字符串)
简要说明: 匹配第一个参数, 并用第二个参数替换
- 第一个参数:
reg|subStr: 用于匹配被替换的字符串中的子字符串的正则表达式或子字符串- 正则表达式如果没有
g修饰符, 则和subStr一样只替换第一个匹配到的字符串let str = "123abc123" let resStr0 = str.replace(/\d+/, "xxx") // 非全局匹配 let resStr1 = str.replace(/\d+/g, "xxx") // 全局匹配 let resStr2 = str.replace("123", "xxx") console.log(resStr0, resStr1, resStr2) //=> "xxxabc123", "xxxabcxxx", "xxxabc123"
- 正则表达式如果没有
- 第二个参数:
newSubStr|callbackFn: 对每次正则匹配的结果用newSubStr或callbackFn的返回值替换newSubStr: 有特殊的用法(在字符串中插入特殊的变量名)-
$n:100 > n >= 1, 表示从 1 开始的捕获let str = "123.456".replace(/(\d+)\.(\d+)/, "$2.$1") // 该正则匹配到的第一组捕获是 "123", 第二组捕获是 "456" console.log(str) //=> "456.123" -
$<name>: 当有具名捕获组时, 可以用$+<名字>来表示对应捕获的内容let str = "123.456" let reg = /(?<left>\d+)\.(?<right>\d+)/ let newSubStr = "$<right>+$<left>" str.replace(reg, newSubStr) //=> "456+123" -
$&: 表示当次正则匹配到的子字符串"123.456".replace(/\d+/g, "0$&") //=> "0123.0456" /** * 由于是全局匹配, 所以会进行多次匹配 * 第一次正则匹配的结果是 "123", 所以 "$&" 代表的就是 "123" * 对于第一次匹配, 替换为 "0$&", 即替换为 "0123" * 第二次正则匹配的结果是 "456", 所以 "$&" 代表的就是 "456" * 对于第二次匹配, 替换为 "0$&", 即替换为 "0456" */ -
$`:$+`(反引号)表示当前所匹配的子串的左边的内容$':$+'(单引号)表示当前所匹配的子串的右边的内容let str = "123.456".replace(/\./, "{left: $`, right: $'}") // 该正则匹配到字符串中的 ".", 并用 "{left: $`, right: $'}" 替换 console.log(str) //=> "123{left: 123, right: 456}456"
-
callbackFn(subStr, $1, $2, ..., offset, str, groups): 返回值替代这次正则表达式所匹配的子字符串subStr: 表示当前正则匹配到的字符串$1, $2, ...: 表示分组捕获到的字符串offset: 表示当前所匹配到的子字符串在源字符串中的起始下标str: 被匹配的源字符串groups: 如果有具名捕获组的话, 就为对应具名捕获组对象, 否则为 undefined
let str = "this is a string" let reg = /\b(\w{1})\w*\b/g str.replace(reg, (subStr, capture1, offset, str, groups) => { console.log(subStr, capture1, offset, str, groups) //=> "this", "t", 0, "this is a string", undefined //=> "is", "i", 5, "this is a string", undefined //=> "a", "a", 8, "this is a string", undefined //=> "string", "s", 10, "this is a string", undefined return subStr + "233" }) //=> "this233 is233 a233 string233" // 在上面的例子中, 一共进行了四次匹配替换, 最后返回最终结果
2.4 String.prototype.search(reg)
返回与对应正则表达式匹配的子字符串在源字符串中的起始下标, 如果无法匹配则返回 -1
let str = "abc123"
let reg = /\d+/
str.search(reg) //=> 3
2.5 String.prototype.split([separator[, limit]])(并不修改源字符串)
以传入的 separator 作为分隔符, 将分割后的结果存放到一个数组中并返回该数组, 如果有 limit, 则表示数组中的元素最多只能有 limit 个
separator:string|reg如果没有匹配到, 则以整个字符串作为数组的一个元素; 如果separator为空字符串, 则源字符串中的每一个字符都是数组的一个元素
const str = "this is a string"
str.split() //=> ["this is a string"]
str.split(/\b/) //=> ["this", " ", "is", " ", "a", " ", "string"]
str.split(" ") //=> ["this", "is", "a", "string"]
str.split(" ", 2) //=> ["this", "is"]