这二者表示的是括号最原始的功能,强调括号内的正则是一个整体,即提供子表达式
-
分组:
/a+/
匹配连续出现的 a,而要匹配连续出现的ab
时,需要使用/(ab)+/
let regx = /(ab)+/g let str = "ababa abbb" console.log(str.match(regx)) //[ 'abab', 'ab' ]
-
分支结构:多选分支结构
(p1|p2)
,提供分支表达式的所有可能let reg = /^I love (you|myself)$/ console.log(reg.test("I love you"))//true console.log(reg.test("I love myself"))//true
使用分组引用可以进行数据提取,以及替换操作
let reg = \(\d{4})-(\d{2})-(\d{2})\
提取数据、年、月、日
let reg = /(\d{4})-(\d{2})-(\d{2})/
let str = '1234-12-12'
console.log(str.match(reg))
// [
// '1234-12-12',
// '1234',
// '12',
// '12',
// index: 0,
// input: '1234-12-12 2020-02-02',
// groups: undefined
// ]
-
match
返回一个数组,第一个元素时整体匹配的结果,然后是各个分组(括号里)匹配的内容,然后匹配下标,最后是输入文本- 如果使用
g
修饰符,match 返回的数据格式不一样
- 如果使用
-
使用正则实例对象
exec
let reg = /(\d{4})-(\d{2})-(\d{2})/
let str = '1234-12-12'
console.log(reg.exec(str))
// [
// '1234-12-12',
// '1234',
// '12',
// '12',
// index: 0,
// input: '1234-12-12',
// groups: undefined
// ]
- 使用构造函数的全局属性
$1
~$9
let reg = /(\d{4})-(\d{2})-(\d{2})/
let str = '1234-12-12'
reg.test(str)
console.log(RegExp.$1)//1234
console.log(RegExp.$2)//12
console.log(RegExp.$3)//12
将
yyyy-mm-dd
格式替换成mm/dd/yyyy
let reg = /(\d{4})-(\d{2})-(\d{2})/
let str = '1234-12-12'
let result = str.replace(reg, "$2/$3/$1")
console.log(result)//12/12/1234
- 等价于一下这两种
let result = str.replace(reg, function () {
return `${RegExp.$2}/${RegExp.$3}/${RegExp.$1}`
})
//第二种
// let result = str.replace(reg, function (match, year, month, day) {
// return `${month}/${day}/${year}`
// })
除了相应 API 引用分组,也可以在正则本身里引用分组。但只能引用之前的分组,即反向分组
- 例如需要正则匹配如下三种格式
2012-12-12
2012/12/12
2012.12.12
- 例如写成如下的正则,不仅匹配了要求的情况,还匹配了
1234-12/12
这种情况
const regex = /\d{4}(-|\/|\.)\d{2}(-|\/|\.)\d{2}/;
let str = '1234-12/12'
console.log(regex.test(str))//true
- 如果使用反向引用可以解决这样的问题
const regex = /\d{4}(-|\/|\.)\d{2}\1\d{2}/;
let str = '1234-12/12'
console.log(regex.test(str))//false
括号嵌套:会以左括号的开括号位准
const regex = /((\d)(\d(\d)))\1\2\3\4/
const string = "1231231233"
console.log( regex.test(string) ) // true
console.log( RegExp.$1 ) // 123
console.log( RegExp.$2 ) // 1
console.log( RegExp.$3 ) // 23
console.log( RegExp.$4 ) // 3
$1
匹配的是((\d)(\d(\d)))
$2
匹配的是(\d)
$3
匹配的是(\d(\d))
$4
匹配的是(\d)
-
\1
表示的是第一个分组的内容,第一个开括号对应的分组是123
-
\2
表示的时第二个分组的内容,第二个开括号对应的分组是1
-
\3
表示的时第三个分组的内容,第三个开括号对应的分组是23
-
\3
表示的时第四个分组的内容,第四个开括号对应的分组是3
\10
:第十个分组不是\1
和0
let reg = /(1)(2)(3)(4)(5)(6)(7)(8)(9)(#) \10+/
let str = "123456789# ####"
console.log(reg.test(str))//true
- 如果需要匹配 \1 和 0,需要使用
(?:\1)0
或者\1(?:0)
引用不存在的分组,正则不会报错,而是反向引用的字符本身。
- 例如
\2
就匹配\2
,表示对 2 进行转义的意思
let reg = /\1\2/
let str = "\1\2"
console.log(reg.test(str))//true
分组后有量词
- 如果分组后有量词,分组最终捕获到的数据是最后一次的匹配,
(\d)-->5
let reg = /(\d)+/
let str = "12345"
console.log(str.match(reg))
//[ '12345', '5', index: 0, input: '12345', groups: undefined ]
- 对于反向引用也是这样
let reg = /(\d)+ \1/
let str1 = "12345 5"
let str2 = "12345 1"
console.log(reg.test(str1))//true
console.log(reg.test(str2))//false
非捕获括号:之前文章出现的括号,都会捕获他们匹配到的数据,以便后续使用,因此称之为是捕获型分组和捕获型分支
-
如果只想要括号最原始的功能,而不引用它,即即不再 API 中引用也不在正则里的反向引用
-
此时可以使用非捕获括号
(?:p)
和(?:p1|p2|p3)
let regx = /(?:ab)+/g let str = "ababa abbb" console.log(str.match(regx)) //[ 'abab', 'ab' ]
-
字符串
trim
方法function trim(str) { //return str.replace(/^\s*|\s*$/g, "") return str.replace(/^\s*(.*?)\s*$/g, "$1") }
-
将每个单词的首字母转化为大写
function titleize(str) { return str.toLowerCase().replace(/(?:^|\s)\w/g, function (c) { return c.toUpperCase() }) }
-
驼峰化
function camelize(str) { return str.replace(/[-_\s]+(.)?/g, function (match, c) { return c ? c.toUpperCase() : "" }) }
- 其中分组
(.)
表示首字母。单词的界定是,前面的界定是,前面可以是多个-
,_
或者\s
。 - 使用
?
是为了防止 str 的尾部可能不是单词字符,例如"-moz-transform "
- 其中分组
-
中划线化
function dashsize(str) { return str.replace(/([A-Z])/g, '-$1').replace(/[-_\s]+/g, '-').toLowerCase(); }