js正则表达式,js中的象形文字
。正则表达式(英语:Regular Expression,在代码中常简写为regex、regexp或RE)使用单个字符串来描述、匹配一系列符合某个句法规则的字符串搜索模式,可用于文本搜索和文本替换。
JS 正则表达式(RegExp对象)
- 正则创建的两种方式 正则只是针对字符串 默认区分大小写
1.patt=new Regexp('规则','g')或patt=new Regexp(/\d{6-10}/g)
动态创建规则必须是字符串 如有\或特殊字符需用\转义
2.patt=/\d{6-10}/g
字面量方式 不要写引号 需要传参的时候必须用new Regexp
正则的六个方法
1./\d+/.test(字符串)
检索字符串中的指定值 返回true
或false
2./\d+/.exec(字符串)
检索字符串中的指定值 返回值是被找到的值 没有返回null
3.str.replace(/\d+/,"hello"或callback)
查找并替换 匹配成功返回替换后的字符串
4.str.match(/\d+/)
正则去匹配字符串 匹配成功返回匹配成功的数组 不成功返回null
5.str.search(/\d+/)
正则去匹配字符串 匹配成功返回位置,失败返回-1
6.str.split(/-/)
用于使用字符串或正则表达式分隔字符串正则默认都是匹配成功就结束了,不会继续匹配,只匹配一次 要全部匹配则要加修饰符g(全局匹配)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26// new RegExp("e") 声明正则
var str = "The best things is sleeping"
var patt1 = new RegExp("e")
console.log(patt1.test(str)) //true
console.log(patt1.exec(str)) //["e", index: 2, input: "The best...", groups: undefined]
var patt = /e/
console.log(str.search(patt)) //2
console.log(str.match(patt)) //["e", index: 2, input: "The best...", groups: undefined]
console.log(str.replace(patt, 'E')) //ThE best things is sleeping
// 使用 /\d{2}/ 声明正则
var str = '我日西安水电费贱贵大傻逼阿达'
var patt = /我日|贱|大傻逼/g
var result = str.replace(patt,function(s){
var res = ''
for(var i=0;i<s.length;i++){
res += '*'
}
return res
})
console.log(result) //**西安水电费*贵***阿达
// 去掉前后空格
var re1 = /^\s+|\s$/g
console.log(' as da '.replace(re1, '')) //as da
// 使用split分日期隔字符串
let dateStr = '2020-09-08 16:18:22'
dateStr.split(/-|:|\s/) // ['2020', '09', '08', '16', '18', '22']修饰符
i 不区分大小写字母的匹配
g 执行全局匹配
m 执行多行匹配 放在/后面 /e/gi
表达式
[abc]
用于查找方括号之间的任意一个(字符类)/[abc]/
[^abc]
用于查找任何不在方括号之间的字符/[^abc]/
|
或、左右两侧有一个匹配到就可以a|b
()
匹配子项或分组操作[a-z]
范围 [a-z][\b]
退格直接量注: 匹配子项 把正则的整体叫做(母亲) 然后把左边第一个小括号里面的正则 叫做第一个子项(第一个孩子) 第二个小括号就是 第二个子项str.replace(patt,function(母亲,第一个子项,第二个子项){}
元字符 转义字符
.
查找除换行符之外任意字符\w
用于查找字符 字符包括[A-Za-z0-9_]
\W
非字符[^A-Za-z0-9_]
\d
用于查找数字0-9
\D
非数字\s
用于查找空白(空格tab
回车 换行)\S
非空白\b
独立的部分(单词边界)(起始 结束 空格)\B
非独立的部分(非单词边界)\1或\2..
重复的第一个子项,第二个子项量词(频率匹配) 匹配不确定的次数 大括号
{}
量词+
一次或多次*
任意次?
零次或一次{n}
必须是n次{n,}
至少n次{n,m}
最少n次,最多m次$
匹配以某字符结尾^
匹配以某字符开始捕获分组和后向引用
当一个模式的全部或者部分内容由一对括号分组时,它就对内容进行捕获并临时存储与内存中。可以通过后向引用重用捕获的内容。
\1或者$1 这里\1或$1引用的是第一个捕获的分组,而\2或$2引用的是第二个捕获的分组,以此类推。1
2
3/(\w)\1+/g; //(\w) 变成子项 \1和前面子项相同 +多个
// \1 \2 \3……\9 \10 ---匹配模式中的后向引用
// $1 $2 $3……$9 $10 ---替换模式中的组的引用捕获分组和非捕获分组
() 表示捕获分组, ()会把每个分组里的匹配的值保存起来, 使用$n(n是一个数字, 表示第n个捕获组的内容)
(?:) 表示非捕获分组, 和捕获分组唯一的区别在于, 非捕获分组匹配的值不会保存起来
1
2
3
4
5
6
7
8// 正则表达式中的每个`()`,都是一个子表达式,每个子表达式都会自动获得一个从`1`开始的编号替换时,可用`$n`,指代本次匹配中第`n`个子表达式的对应内容
var reg = /^(\d{2})(\d{4})(\d{4})(\d{2})(\d{2})(\d{2})(\d)(\d|X)$/
var reg1 = /^(\d{2})(\d{4})(\d{4})(\d{2})(\d{2})(?:\d{2})(\d)(?:\d|X)$/
var str = "14272619960919121X"
console.log(reg.exec(str)) // 捕获分组
// ['14272619960919121X', '14', '2726', '1996', '09', '19', '12', '1', 'X', ...]
console.log(reg1.exec(str)) // (?:) 在分组中?:是只匹配不捕获
// ['14272619960919121X', '14', '2726', '1996', '09', '19', '1', ...]前向声明(先行断言)或反前向声明(先行否定断言)
1
2
3
4
5
6
7
8// (?=字符) 或 (?!字符) 是不计入返回结果的
//exp1(?=exp2) 前向声明 exp1只有在exp2前面才匹配
//exp1(?!exp2) 反前向声明 exp1只有不在exp2前面才匹配
var str = '90利率101%,总额100';
var re = /\d+(?=%)/g; // 只匹配%前面紧跟的数字
var re1 = /\d+(?!%)/g; // 只匹配不在%前面的数字
console.log(str.match(re)) // ['101'] => 只匹配在%前面紧跟的数字
console.log(str.match(re1)) // ['90', '10', '100'] => 只匹配不在%前面的数字后顾(后行断言)或负后顾(后行否定断言)
1
2
3
4
5
6
7// (?<=exp2)exp1 只有exp1在exp2后面才匹配
// (?<!exp2)exp1 只有exp1不在exp2后面才匹配
var str = 'banana is 80, apple is $100, pear is 90元';
var re = /(?<=\$)\d+/g; // 只匹配$后面紧跟的数字
var re1 = /(?<!\$)\d+/g; // 只匹配不在$后面的数字
console.log(str.match(re)) // ['100'] => 只匹配在$后紧跟的数字
console.log(str.match(re1)) // ['80', '00', '90'] => 只匹配不在$后面的数字正则表达式 \1 \2 反向引用之类的问题
1
2
3
4
5
6
7// \0 \1 \2 都要和正则表达式集合()一起使用
// \1表示重复正则第一个圆括号内匹配到的内容
// \2表示重复正则第二个圆括号内匹配到的内容
var str = 'abdcbcdadcabce'
console.log(str.split('').sort().join('').match(/([a-z])\1*/g)) // ["aaa", "bbb", "cccc", "ddd", "e"]
var RegExp1 = /^(123)(456)\1$/ // 123456123
var RegExp1 = /^(123)(456)\2$/ // 123456456
replace
更多应用
格式化字符串:正则表达式中的每个
()
,都是一个子表达式,每个子表达式都会自动获得一个从1
开始的编号替换时,可用$n
,指代本次匹配中第n
个子表达式的对应内容1
2
3
4
5
6var date = '20190108180155'
var reg = /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/
date.replace(reg, '$1年$2月$3日 $4:$5:$6') // "2019年01月08日 18:01:55"
date.replace(reg, '$1-$2-$3 $4:$5:$6') // "2019-01-08 18:01:55"
// 隐藏手机号中间4位
'18855558888'.replace(/(\d{3})\d*(\d{4})/g, '$1****$2') // 188****8888replace
第二个参数为函数时,匹配几次执行几次1
2
3
4
5
6let str = "19861289"
const arr = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']
str = str.replace(/\d/g, function () {
return arr[arguments[0]]
})
console.log(str) // 壹玖捌陆壹贰捌玖
其他
- 使用正则
test()
第一次是true
,第二次是false
正则表达式 lastIndex 属性用于规定下次匹配的起始位置。RegExp.exec( ) 和 RegExp.test( ) 找到的,它们都以 lastIndex 属性所指的位置作为下次检索的起始点。lastIndex 属性是可读可写的, 需配合修饰符g使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18var s1 = "1R1MRLPRL";
var reg = /mrlp/ig;
console.log(reg.test(s1)) // true
console.log(reg.lastIndex) // 7
console.log(reg.test(s1)) // false
// 方法一 直接去掉 g
var s1 = "1R1MRLPRL"
var reg = /mrlp/i
console.log(reg.test(s1)) // true
console.log(reg.lastIndex) // 0
console.log(reg.test(s1)) // true
// 方法二 当必须使用g时 将lastIndex重置为0
var s1 = "1R1MRLPRL"
var reg = /mrlp/ig
console.log(reg.test(s1)) // true
console.log(reg.lastIndex) // 7
reg.lastIndex = 0
console.log(reg.test(s1)) // true
贪婪匹配与惰性匹配
默认贪婪匹配
贪婪匹配是先看整个字符串是否匹配,如果不匹配,它会去掉字符串的最后一个字符,并再次尝试。如果还不匹配,那么再去掉当前最后一个,直到发现匹配或不剩任何字符1
2
3
4var str = 'aaa<div style="font-color:red;">123456</div>bbb'
str.match(/<.+>/); // <div style="font-color:red;">123456</div>
var str2 = 'abcdabceba'
str.match(/.+b/) // abcdabceb?惰性匹配 尽可能少的匹配
惰性匹配是从左侧第一个字符开始向右匹配, 先看第一个字符是不是一个匹配, 如果不匹配就加入下一个字符再尝式匹配, 直到发现匹配1
2
3
4var str = 'aaa<div style="font-color:red;">123456</div>bbb'
str.match(/<.+?>/) // <div style="font-color:red;">
var str2 = 'abcdabceba'
str.match(/.+?b/) // ab