您的位置:首页 > Web前端 > JavaScript

JavaScript 正则match的使用体会

2015-09-19 17:16 543 查看
js中的正则表达式match方法如果学会使用,真的可以极大的提高字符串处理的工作效率,但也是所有正则方法中最难懂的一个,下面写出match方法获取字符串的几个基本方法。1、获得一个字符串中的单个匹配值:比如我要获取http://www.baidu.com中的域名和后缀,也就是baidu和com,可以这么写
var str = "http://www.baidu.com"
<pre name="code" class="javascript">var arr = str.match("(www\.)(.*)(\.com)");
console.log(arr[0]);//www.baidu.com
console.log(arr[1]);//www.
console.log(arr[2]);//baidu
console.log(arr[3]);//.com
console.log(arr[4]);//undefined
可以看出,match方法返回的是一个数组,这个数组的[0]是按照给定的字符串进行拼配到的整体值,然后[1],[2],[3]....是根据用户用括号括起的每一个子表达式对arr[0]进行再匹配,获得一个匹配两次后的值;如果我们要匹配.com.org.cn等不同后缀的值,可以这样写:
var arr = str.match("(www\.)([^\.]*)(\.+)");
返回数组与上面相同。但是这样写是不对的:
var arr = str.match("(www\.)(.*)(\..*)");
<pre name="code" class="javascript"><pre name="code" class="javascript">console.log(arr[0]);//www.baidu.com
console.log(arr[1]);//www.
console.log(arr[2]);//baidu.com
console.log(arr[3]);//
console.log(arr[4]);//undefined
原因是按照.*这种任意字符串匹配,一般以先匹配到的条件开启“贪婪模式”,也就是尽可能多的匹配字符;因为baidu.com满足.*的条件,所以全部被匹配。为了避免这种情况发生,一般是设置匹配终止字符,也就是上面正确例子里的[^\.]*,这样匹配到.就会自动停止同理,这样写也是不对的:
var gaga2 = "http://www.baidu.com".match("(www\.)(.*?)\..*");//(虽然这里使用了最小化模式,但是没有没有得到想要的结果)
console.log(gaga2[0]);//www.baidu.com
        console.log(gaga2[1]);//www.
        console.log(gaga2[2]);//""
        console.log(gaga2[3]);//undefined
2、获得一个数组的多个匹配值比如要将连续字符串” http://www.baidu.com http://www.sina.cn.com http://www.situ.org http://www.taobao.com“ 中的每个网址分离开先给出一个错误例子:
var str2 = "http://www.baidu.com http://www.google.com http://www.youku.com http://www.taobao.com http://www.situ.org";

var arr2 = str2.match("(http://[^(http)]*)(http://[^(http)]*)(http://[^(http)]*)(http://[^(http)]*)");
返回结果如下:
<pre name="code" class="javascript"><pre name="code" class="javascript">console.log(arr2[0]);//"http://www.baidu.com http://www.google.com http://www.youku.com http://www." console.log(arr2[1]);//"http://www.baidu.com "
console.log(arr2[2]);//"http://www.google.com "
console.log(arr2[3]);//"http://www.youku.com "
console.log(arr2[4]);//"http://www."
<pre name="code" class="javascript"><pre name="code" class="javascript"><pre name="code" class="javascript">console.log(arr2[5]);//"undefined
在这里,虽然设置了[^(http)]作为中断,但是js会将h,t,p中的任意一个字符作为中断符,所以接地刀taobao.com的‘t’时,就终止匹配了,而且[^(http)]与[^http],[^‘http’]的作用效果相同,且^(http)这种写法会报错。结论:js中的非^只支持单个字符作为条件,不能接纳字符串为条件。那么要想获取分离开的网址就不能使用match方法了,好在js中还有另一种更专业的方法,也就是正则表达式对象,用法如下:
var reg2 = /http:\/\/www\.([^\.]*)/g
console.log(reg2.exec(str2));//Array [ "http://www.baidu", "baidu" ]
console.log(reg2.exec(str2));//Array [ "http://www.google", "google" ]
console.log(reg2.exec(str2));//Array [ "http://www.youku", "youku" ]
console.log(reg2.exec(str2));//Array [ "http://www.taobao", "taobao" ]
console.log(reg2.exec(str2));//Array [ "http://www.situ", "situ" ]
console.log(reg2.exec(str2));//null
 /http:\/\/www\.([^\.]*)/g是一个正则表达式对象,不要用引号包围,不然会变成字符串对象,正则表达式对象有自己的多个方法,其中exec(String)用于匹配字符串其中,/g的作用是全局查找,如果不写/g那么每次执行reg2.exec(str2)得出的结果都是相同的(第一次匹配的值),如果协商以后第二次调用就会获得第二个匹配值,但是注意match()方法不管加不加/g每次获得值都是相同的,所以不能用来匹配大字符串的子字符串;通过这种方法可以轻松的取得域名,但是如果要想取得完整地址,像下面这样写(错误示范)
var reg2 = /(http:\/\/www\.[^\.]*\..*?)http/g        console.log("start");        console.log(reg2.exec(str2));//Array [ "http://www.baidu.com http", "http://www.baidu.com " ]        console.log(reg2.exec(str2));//Array [ "http://www.youku.com http", "http://www.youku.com " ]        console.log(reg2.exec(str2));//null        console.log(reg2.exec(str2));//Array [ "http://www.baidu.com http", "http://www.baidu.com " ]        console.log(reg2.exec(str2));//Array [ "http://www.youku.com http", "http://www.youku.com " ]        console.log(reg2.exec(str2));//null
?为最小模式(相对于贪婪模式),可以防止一个.*匹配到尾的情况上面表达式的原意为从一个http匹配到另一个http,将中间的内容取出,但实际操作出来的结果是隔一个地址取一个,而且最后一个由于没有http结尾直接为null。不过从这个错误例子可以得出一个很重要的结论:exec()每次得到的结果中的字符不会参与下次的匹配,即下次匹配时上次的匹配值就像从源字符串中删去了一样。比如aaaaaaaaa 匹配aaa的话只会得到到3个结果,而任意相邻匹配的话会有7个个结果。从上面可以看出匹配出域名(baidu,youku)要比匹配完整网址要简单,因为域名有明显的分隔符——左右都是点号,那么根据这个原理,不妨给大字符串的每个网址添加一个分隔符,再去匹配就比较容易了;因为案例中每个网址都以http开头,那么就使用一个曲线救国的方式,先拿http开刀,手动给相邻网址之间添加分隔符,然后借此分隔符匹配:
reg3 = /(http:[^$]*)/g;console.log(str3);console.log(reg3.exec(str3));//Array [ "http://www.baidu.com ", "http://www.baidu.com " ]console.log(reg3.exec(str3));//Array [ "http://www.google.com ", "http://www.google.com " ]console.log(reg3.exec(str3));//Array [ "http://www.youku.com ", "http://www.youku.com " ]console.log(reg3.exec(str3));//Array [ "http://www.taobao.com ", "http://www.taobao.com " ]console.log(reg3.exec(str3));//Array [ "http://www.situ.org", "http://www.situ.org" ]console.log(reg3.exec(str3));//null
同理用如下代码可以同时获取完整网址和域名
str3 = str2.replace(/http:/g, "$http:")console.log(str3);//$http://www.baidu.com $http://www.google.com $http://www.youku.com $http://www.taobao.com $http://www.situ.orgreg3 = /http:\/\/www\.([^\.]*?)\.[^$]*/g;          console.log(reg3.exec(str3));//Array [ "http://www.baidu.com ", "baidu" ]        console.log(reg3.exec(str3));//Array [ "http://www.google.com ", "google" ]        console.log(reg3.exec(str3));//Array [ "http://www.youku.com ", "youku" ]        console.log(reg3.exec(str3));//Array [ "http://www.taobao.com ", "taobao" ]        console.log(reg3.exec(str3));//Array [ "http://www.situ.org", "situ" ]<pre name="code" class="javascript">        console.log(reg3.exec(str3));//null

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: