JavaScript通过RegExp对象支持正则表达式
实例化正则表达式的方式:
1、字面量 var reg=/\bis\b/g
2、RegExp构造函数 var reg = new RegExp( ‘\bis\b’ , ‘g’ );这里反斜线\使用了两次因为需要转译。
修饰符:
g:全文搜索,默认是只搜索第一个,global
i:忽略英文大小写,默认是判别英文大小写的,ignore
m:多行搜索,multiple
(修饰符放在//的最后)
字符类:
一般情况下正则表达式的一个字符对应字符串的一个字符,
如:表达式ab/t的含义是ab+tab(换行符)
有时需要匹配符合某一特征的一类字符则需要使用元字符[]来构建一个类
如:[abc]把字符a或b或c归为一类,含义a或b或c中的一个就会匹配到
字符类取反
使用:元字符 ^ 创建反向类/负向类。意思是不属于某一类的内容
如:[abc^]的含义是匹配到不是a或b或c的内容
范围类
比如说要选取字母a-t的内容,如果手动输入[abcdefghijklmnopqrst]就很麻烦,正则表达式就为此提供了一个范围类。
只需要使用[a-z]就可以获取了。(这是个闭区间)
在范围类里也是可以连写的
比如要取a-z的大写字母和小写字母[a-zA-Z]
需要注意的是如果是在x-y这种情况里面,“-”是表示从。。。到。。。的,如果想要匹配到“-”只需要再在后面加上一个“-”就可以了。如:[a-b-]
预定义类
匹配常见的字符类
. 等价类 [ ^\r\n] 除了回车和换行符之外的所有字符
\d等价类**[0-9]数字字符
\D等价类[ ^0-9]非数字字符
\s等价类[ \t\n\x0B\f\r]空白符(即是空格)
\S等价类[ ^\t\n\x0B\f\r]非空白符(不是空格)
\w等价类[a-zA-Z_0-9]单词字符(字母数字下划线)
\W等价类[ ^a-zA-Z_0-9]**非单词字符
边界匹配字符
^ :以XXX开始(在中括号[]里面的时候才表示取反,不在中括号里面的时候就表示以XXX开始)
比如:要匹配@123@abc@中的第一个“@”,那么就应该用/^@/g;匹配最后一个@用 /@$/g
需要注意的是,这里的以XXX开始只是按照行来的,也就是第一行的第一个XXX,如果要匹配多行的第一个XXX则需要在后面加入m(多行搜索),/@ $/gm
$ :以XXX结束
\b:单词边界------\bis\bg 在全局下匹配单词为is的字符串
\B :非单词边界
量词
*?出现0或1次(不大于1次)
+出现1次或多次(不小于1次)
出现0次或多次(任意次)
{n}出现n次
{n,m}出现n到m次
{n,}至少出现n次
(如果没有量词则默认是{1})
贪婪模式与非贪婪模式
正则表达式默认是贪婪模式,也就是说会尽可能的匹配更多的字符,像/\w{2,6}/g 会先匹配到一个单词字符然后再看这个单词字符后面是不是还有5个别的单词字符,如果有就选中这6个字符;如果没有则看它后面有没有4个单词字符。。。。。。直到满足匹配或者这个单词字符之后没有别的单词字符再继续向前匹配新的单词字符。
也就是说贪婪模式下会尽可能的匹配多的量词规定的内容。
非贪婪模式就正相反,它会从最小的匹配。
如果需要改为非贪婪模式则:在**量词之后加?**就可以了
分组
比如,有时想要选中一整个单词3次,使用Happy{3}的结果是只选中了距离量词最近的n三次,这时就需要使用分组符()达到分组的效果(Happy){3},量词只会作用于在它前面的那一个分组或者符号。
或
|
如:happy|sad
反向引用
使用$1,$2,$3来作为变量一样的代表第一个分组,第二个分组,第三个分组
比如:
我们需要把2017-01-1982给倒过来为1982-01-2017,此时就需要把2017作为一个分组,01作为一个分组,1982作为一个分组,使用$3$2$1将其顺序换过来
“2017-01-1982”.replace(/(\d{4})-(\d{2})-(\d{4})/g,"$3$2$1")
忽略分组
在分组中加入?:就可以忽略这个分组了
前瞻
正则表达式从文本的头部向尾部进行解析,文本尾部方向称之为“前”
前瞻就是在匹配到正则表达式的时候继续再往前检查是否符合断言
(后顾/后瞻就是与前瞻相反的反向,但JAVASCRIPT不支持后顾)
符合某个断言:肯定 /正向匹配
不符合某个断言:否定 /负向匹配
正向前瞻:exp(?=assert)
负向前瞻:exp(?!assert)
(assert为断言)
正向前瞻如:
=> 'a23’.replace(/\w(?=\d)/g,“X”)
<= "X23"
意思就是:先判断是不是英文字符,然后再看这个英文字符的前面有没有数字,如果有则这个英文字符匹配,如果没有则不匹配
负向前瞻如:
=> 'a23’.replace(/\w(?!\d)/g,“X”)
<= "aXX"
JS对象属性
修饰符:
g:全文搜索,默认是只搜索第一个global 默认false
i:忽略英文大小写,默认是判别英文大小写的ignore 默认false
m:多行搜索multiple 默认false
lastIndex:当前表达式匹配内容的最后一个字符的下一个位置
source:正则表达式的文本字符串
(全都是只读的,不能写入设置,且全都放在//后面)
text和exec方法
**RegExp.prototype.text(str):测试str中是否存在匹配正则表达式模式的字符串。!!只要存在一个符合的就会返回true,**不会管其他不符合的事情!
var reg1=/\w/;
var reg2=/\w/g;
console.log(reg1(“a”));----true
console.log(reg1("@21313"));—false
console.log(reg1("@21313a12312"));—true 因为有一个a是符合的
但是对于reg2来说,因为其具有g全局标志,所以要注意它的lastIndex属性。
比如:
var regexp = /abcd/;
var str = ‘12ab34’;
console.log((regexp.test(str)));—true因为ab是符合的,此时lastIndex跳到ab上,下一次从3开始检索
console.log((regexp.test(str)));—false因为34不匹配正则表达式
console.log((regexp.test(str)));—重新从1开始匹配
**RegExp.prototype.exec(str)😗*与text不同的是,exec返回的是数组,这个数组里,第一个值是index,是首个匹配到的字符串的位置,第二个值是匹配到的那个数组,第三个值及其之后都是分组()里的匹配到的值。
在全局标志下,还可以循环使用exec匹配到所有符合正则表达式的字符串,依靠的是lastIndex。
字符串对象方法
String.prototype.search(reg):传入参赛reg可以是字符串也可以是正则表达式。用于检索是否存在传入的子字符串或者是否存在匹配正则表达式的字符串。
方法返回第一个匹配的结果的位置(0、1、2…n-1),查找不到就返回-1.(只返回一个)
String.prototype.match(reg):检索字符串,找到一个或多个匹配reg的字符串。
在非全局调用(reg没有g):
返回的数组的第一个元素是与正则表达式匹配的字符串,第二个元素是这个匹配的字符串中的正则表达式的分组对应的内容。(只匹配并返回第一个匹配的字符串)
并且返回的数组还有两个对象属性:
index:匹配到的第一个字符串的起始字符在字符串中的位置。
input: 放的是这个被match的字符串
在全局调用下(reg有g):
没有input、index,分组属性,返回的数组中只有匹配到的字符串
匹配并返回所有的字符串
String.prototype.split(reg)
用法一:
=> “a,b,c,d”.split(",")
<= (4) [“a”, “b”, “c”, “d”]
以参数reg为标准,将字符串分割开来并且依次传入数组。
用法二:
=> “a1b2c3d4”.split(/\d/)
<= (5) [“a”, “b”, “c”, “d”, “”]
以正则表达式reg匹配字符串作为分割字符串的标准。
String.prototype.replace(reg)
用法一:
=> “a1b1c1”.replace(“1”,2)
<= “a2b1c1”
这种方法来替换的话就只会替换第一个匹配的子字符串(因为实际上还是将第一个参数“1”给隐式的转为了"/1/",所所以只会匹配并替换第一个),如果想要全部匹配并替换的话应该将第一个参数传入正则表达式。
用法二:
=> “a1b1c1”.replace("/\d/g",2)
<= “a1b1c1”
用法三:
str.replace(reg,function(match,group1,group2…groupN,index,origin){
return X;----return什么,被匹配到的子字符串就会替换为 什么
})
function的参数:
function的第一个参数为被匹配到的子字符串,第二、三。。。N个参数为每次匹配到的子字符串的对应的正则表达式内的分组,倒数第二个参数为每次匹配到的子字符串的首子字符串的位置,origin为str即初始的replace方法作用的字符串。
(这些参数是严格按照顺序对应各自的内容的,可以按照顺序更改其参数名,因为参数名无所谓,只要顺序正确就行了)
需要注意的是:这三种用法都不会对原来的字符串进行任何的改变,只是会返回一个在原字符串的基础上进行替换的新字符串,这个返回的新字符串才是我们所需要的。