括号(2)
前面我们曾经讨论过一次括号的问题,见下面这个例子:
<script type="text/javascript">
function execReg(reg,str){
var result = reg.exec(str);
alert(result);
}
reg = /^(b|c).+/;
str='crazy.grass.com';
execReg(reg,str);
</script>
这个正则是为了实现只匹配以b或者c开头的字符串,一直匹配到换行字符,但是。上面我们已经看到了,可以使用“\1”来反向引用这个括号里的子正则表达式所匹配的内容。而且exec方法也会将这个字正则表达式的匹配结果保存到返回的结果中。
返回结果:crazy.grass.com,c
不记录子正则表达式的匹配结果
使用形如(?:pattern)的正则就可以避免保存括号内的匹配结果。例如:
<script type="text/javascript">
function execReg(reg,str){
var result = reg.exec(str);
alert(result);
}
reg = /^(?:b|c).+/;
str='crazy.grass.com';
execReg(reg,str);
</script>
可以看到返回的结果不再包括那个括号内的字正则表达式多匹配的内容
同理,反向引用也不好使了:
<script type="text/javascript">
function execReg(reg,str){
var result = reg.exec(str);
alert(result);
}
reg = /^(b|c)\1/;
str='ccrazy.grass.com';
execReg(reg,str);
</script>
返回cc,c。cc是整个正则表达式匹配的内容,而b是第一个子正则表达式匹配的内容。
<script type="text/javascript">
function execReg(reg,str){
var result = reg.exec(str);
alert(result);
}
reg = /^(?:b|c)\1/;
str='ccrazy.grass.com';
execReg(reg,str);
</script>
返回null。由于根本就没有记录括号内匹配的内容,自然没有办法反向引用了。
正向预查
形式:(?=pattern)
所谓正向预查,意思就是:要匹配的字符串,后面必须紧跟着pattern!
我们知道正则表达式/crazy/会匹配crazy。同样,也会匹配crazy9中的crazy。但是我们可能希望,crazy只能匹配crazy8中的crazy。这时候就可以像下面这样写:/crazy(?=8)/,看两个实例:
<script type="text/javascript">
function execReg(reg,str){
var result = reg.exec(str);
alert(result);
}
reg = /crazy(?=8)/;
str='crazy9';
execReg(reg,str);
</script>
返回null。
<script type="text/javascript">
function execReg(reg,str){
var result = reg.exec(str);
alert(result);
}
reg = /crazy(?=8)/;
str='crazy8';
execReg(reg,str);
</script>
匹配crazy。
需要注意的是,括号里的内容并不参与真正的匹配,只是检查一下后面的字符是否符合要求而已,例如上面的正则,返回的是crazy,而不是crazy8。
<script type="text/javascript">
function execReg(reg,str){
var result = reg.exec(str);
alert(result);
}
reg = /crazy(?=grass)/;
str='crazygrass';
execReg(reg,str);
</script>
返回是crazy。
<script type="text/javascript">
function execReg(reg,str){
var result = reg.exec(str);
alert(result);
}
reg = /crazy(?=grass)/;
str='crazycao';
execReg(reg,str);
</script>
返回是null,因为crazy后面不是grass
?!
形式(?!pattern)和?=恰好相反,要求字符串的后面不能紧跟着某个pattern,还拿上面的例子:
<script type="text/javascript">
function execReg(reg,str){
var result = reg.exec(str);
alert(result);
}
reg = /crazy(?!grass)/;
str='crazycao';
execReg(reg,str);
</script>
返回crazy
<script type="text/javascript">
function execReg(reg,str){
var result = reg.exec(str);
alert(result);
}
reg = /crazy(?!grass)/;
str='crazycao';
execReg(reg,str);
</script>
返回null
匹配元字符
首先要搞清楚什么是元字符呢?我们之前用过*,+,?之类的符号,它们在正则表达式中都有一定的特殊含义,类似这些有特殊功能的字符都叫做元字符。例如
reg = /c*/;
表示有任意个c,但是如果我们真的想匹配’c*’这个字符串的时候怎么办呢?只要将*转义了就可以了,如下:
<script type="text/javascript">
function execReg(reg,str){
var result = reg.exec(str);
alert(result);
}
reg = /c\*/;
str='c*';
execReg(reg,str);
</script>
返回匹配的字符串:c*。
同理,要匹配其他元字符,只要在前面加上一个“\”就可以了。
正则表达式的修饰符
全局匹配,修饰符g
形式:/pattern/g
例子:reg = /b/g;
后面再说这个g的作用。先看后面的两个修饰符。
不区分大小写,修饰符i
<script type="text/javascript">
function execReg(reg,str){
var result = reg.exec(str);
alert(result);
}
var reg = /b/;
var str = 'BBS';
execReg(reg,str);
</script>
返回null,因为大小写不符合。
<script type="text/javascript">
function execReg(reg,str){
var result = reg.exec(str);
alert(result);
}
var reg = /b/;
var str = 'BBS';
execReg(reg,str);
</script>
匹配到B,这个就是i修饰符的作用了。
行首行尾,修饰符m
形式:/pattern/m
m修饰符的作用是修改^和$在正则表达式中的作用,让它们分别表示行首和行尾。例如:
<script type="text/javascript">
function execReg(reg,str){
var result = reg.exec(str);
alert(result);
}
var reg = /^b/;
var str = 'test\nbbs';
execReg(reg,str);
</script>
匹配失败,因为字符串的开头没有b字符。但是加上m修饰符之后:
<script type="text/javascript">
function execReg(reg,str){
var result = reg.exec(str);
alert(result);
}
var reg = /^b/m;
var str = 'test\nbbs';
execReg(reg,str);
</script>
匹配到b,因为加了m修饰符之后,^已经表示行首,由于bbs在字符串第二行的行首,所以可以成功地匹配。