Skip to content

括号分组

括号提供了分组,便于引用

js
/ab{2}/.test('abb') // true
/(ab){2}/.test('abb') // false 量词对分组的多次引用
/(ab){2}/.test('abab') // true

/((ab){2}){2}/.test('ababab') // false
/((ab){2}){2}/.test('abababab') // true ab*2 --> (abab),abab*2 --> (abababab)

捕获括号

每一个括号在匹配过程中都会开辟一个空间,用于存储分组过程中匹配的数据

使用正则的API(test、exec)分组捕获的数据可以 使用RegExp.$1至RegExp.$9获取

js
var regex = /(\d{4})-(\d{2})-(\d{2})/
var string = "2017-06-12"
console.log( string.match(regex) )
// => ["2017-06-12", "2017", "06", "12", index: 0, input: "2017-06-12"]
// 依次是匹配的数据  ---> 分组数据 ---> 匹配字符串的开始下标 ---> 原始字符串

var regex = /(\d{4})-(\d{2})-(\d{2})/g
var string = "2017-06-12"
console.log( string.match(regex) )
// => ["2017-06-12"]
// match API加 修饰符g 后,只返回匹配的文本组成的数组


// 替换
var regex = /(\d{4})-(\d{2})-(\d{2})/
var string = "2017-06-12"
var result = string.replace(regex, "$2/$3/$1")
console.log(result)
// => "06/12/2017"

反向引用

引用之前出现的分组 \1 至 \10

js
// 验证日期格式规范
var regex = /\d{4}(-|\/|\.)\d{2}\1\d{2}/ // \1 引用之前分组捕获的- / .
var string1 = "2017-06-12"
var string2 = "2017/06/12"
var string3 = "2017.06.12"
var string4 = "2016-06/12"
console.log( regex.test(string1) ) // true
console.log( regex.test(string2) ) // true
console.log( regex.test(string3) ) // true
console.log( regex.test(string4) ) // false

非捕获括号

(:?p) 不进行分组. 不能在API中引用,也不能在正则中使用\1至\9引用

分组命名

用法:在分组的左括号后加上:?<g0>

js
// 体现在match/exec匹配后groups对象

'a-b'.match(/(?<g0>\w-)/)
// ['a-', 'a-', index: 0, input: 'a-b', groups: {g0: 'a-'}]

/(?<g0>\w-)/.exec('a-b')
// ['a-', 'a-', index: 0, input: 'a-b', groups: {g0: 'a-'}]

常用示例

大小驼峰转中划线

js
// 匹配大写字母前面的位置,匹配一个大写字母
'OneTwoThree'.replace(/(?=[A-Z])[A-Z]/g, (match, index) => {
  // console.log(match, index) // match, index为匹配到字符的位置下标【有分组时,index参数往后顺延】

  // 如果位置为0直接小写字母再返回,否则就加个- 再小写返回
  return index === 0 ? match.toLowerCase() : '-' + match.toLowerCase()
})
// 'one-two-three'

中划线转小驼峰

js
// 匹配-  再匹配a-z任意一个
'one-two-three'.replace(/\-[a-z]/g, (match) => {
  return match.replace('-', '').toUpperCase() // 替换-为'', 再转成大写
})
// 'oneTwoThree'

中划线转大驼峰

js
// 难点:第一个字符如何转换
// 思路:匹配开头+一个字母的 或者 一个横杠-加一个字母的
'one-two-three'.replace(/(?<=^)[a-z]|\-[a-z]/g, (match) => {
  // console.log(match)
  return match.replace('-', '').toUpperCase() // 替换-为'', 再转成大写
})
// 'OneTwoThree'