# 正则

# ?=、?<=、?!、?<!、?:的使用和区别

?=

使用:B(?=A) 查找右边是A的B

// 查找所有右边是A的B,并把B改成C
var reg = /B(?=A)/g
"BAB".replace(reg, "C") // CAB
"BABABA".replace(reg, "C") // CACACA

?<=

使用: (?<=A)B 查找左边是A的B

// 查找所有后面是A的B,并把B改成C
var reg = /(?<=A)B/g
"BAB".replace(reg, "C") // BAC
"BABABA".replace(reg, "C") // BACACA

?!

// 查找所有右边不是A的B,并把这个B改成C
var reg = /B(?!A)/g
"BABD".replace(reg, "C") // BACD

?<!

// 查找所有左边不是A的B,并把这个B改成C
var reg = /(?<!A)B/g
"CBADA".replace(reg, "C") // CCADA

?: 非捕获分组

如果正则出现的括号,会对匹配到的括号中的内容分行分组

var reg = /B(D)(F)C/g
"BDFC".replace(reg, function(){
	console.log(arguments)
})

// ["BDFC", "D", "F", 0, "BDFC", callee: ƒ, Symbol(Symbol.iterator): ƒ]

如果括号中首页跟着?:表示当前括号中的内容不进行分组

var reg = /B(?:D)(F)C/g
"BDFC".replace(reg, function(){
	console.log(arguments)
})

// ["BDFC", "F", 0, "BDFC", callee: ƒ, Symbol(Symbol.iterator): ƒ]

# 粟子

匹配从A开头B结尾且中间不包含C的字符串

var reg = /^A[^C]*B/g
"A1254BCFDFDB".match(reg) // ["A1254B"]
"AB".match(reg) // ["AB"]

匹配DOM字符串中的闭合标签

	const unicodeRegExp = /a-zA-Z\u00B7\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u037D\u037F-\u1FFF\u200C-\u200D\u203F-\u2040\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD/
	const ncname = `[a-zA-Z_][\\-\\.0-9_a-zA-Z${unicodeRegExp.source}]*`
	const qnameCapture = `((?:${ncname}\\:)?${ncname})`
	const endTag = new RegExp(`^<\\/${qnameCapture}[^>]*>`)
    console.log('</com-header-1>>'.match(endTag))
/*	0: "</com-header-1>"
	1: "com-header-1"
	groups: undefined
	index: 0
	input: "</com-header-1>>"
	length: 2*/