(转载请注明出处)
昨天读jquery.form的源代码,读到这么一句
url = (url.match(/^([^#]+)/)||[])[1];
原文的解释是:clean url (don't include hash value) -- 可以解释为:把url中hash的部分去掉,即url中#号后面的部分去掉。那么此处的match函数到底是怎么起作用的?
我先看了一下match函数的官方解释,摘录如下:原文地址
match() 方法将检索字符串 stringObject,以找到一个或多个与 regexp 匹配的文本。这个方法的行为在很大程度上有赖于 regexp 是否具有标志 g。
如果 regexp 没有标志 g,那么 match() 方法就只能在 stringObject 中执行一次匹配。如果没有找到任何匹配的文本, match() 将返回 null。否则,它将返回一个数组,其中存放了与它找到的匹配文本有关的信息。该数组的第 0 个元素存放的是匹配文本,而其余的元素存放的是与正则表达式的子表达式匹配的文本。
我做了一个测试:
var url = "http://www.baidu.com#top"; alert(url.match(/^([^#]+)/);
alert弹出的结果是:http:www.baidu.com,http:www.baidu.com
是一个数组,有两个元素,且两个元素一样。我不懂的地方是这两个元素是如何得来的?为什么会有两个一样的元素?
理解这个问题,首先解释的是正则表达式是什么意思:/^([^#]+)/的意思是从字符串的开头开始匹配,匹配一串不为‘#’的字符,所以该正则表达式匹配的是一个url从开头到第一个‘#’之间的字符串。很明显,此处是http://www.baidu.com。那么第二个元素是怎么回事?我仔细看了一下w3c对这个函数的解释,注意到这一句:它将返回一个数组,其中存放了与它找到的匹配文本有关的信息。该数组的第 0 个元素存放的是匹配文本,而其余的元素存放的是与正则表达式的子表达式匹配的文本。这意味着第二个元素是url与子串匹配的结果,这个子串就是正则表达式括号中的部分(我猜的,还没有得到确切的验证),即匹配一段不包含‘#’号的字符串。
那我如果有过个‘#’号呢?
如下例子
var url = "http://www.baidu.com#top#left#right"; alert(url.match(/^([^#]+)/));
返回的值还是:http://www.baidu.com,http://www.baidu.com
这个主要是因为没有加g标记,字符串只匹配一次,所以尽管子串可以不用从头匹配但也因为只匹配一次所以也只能返回第一次匹配的串。下面加上g标记。并修改正则使其不从头开始匹配,代码如下:
var url = "http://www.baidu.com#top#left#right"; alert(url.match(/([^#]+)/g));
此次的返回值是:http://www.baidu.com,top,left,right ,是整个url中所有与正则匹配的串。
之后我有测试了一下所谓子串的问题,我将正则的括号位置改成这样的:/^([^#])+/,这个改动之后,正则匹配的还是从开头到第一个'#'号之间的位置,但其子串意义为匹配不为'#'的字符,一次匹配一个,然后再做测试
var url = "http://www.baidu.com#top#left#right"; alert(url.match(/^([^#])+/));
测试结果是:http://www.baidu.com,m,数组中的第二个元素是m。为什么是m不是h呢,估计是正则匹配的时候只匹配一次的意思是当主正则失配后子正则从当前失配的位置开始匹配。为此我有做了如下两个例子:
例一
var url = "aabbc#top"; alert(url.match(/^([^#]{2})+/));
返回的结果是: aabb,bb
例二
var url = "aabbc#top"; alert(url.match(/^([^#]{1,2})+/));
返回的结果是:aabbc,c
由此,可见子正则是从主正则失配后开始匹配的。但是要证明此结论,还需做更多严谨的测试,或去阅读详细的官方文档。
以上这些见解只是我个人通过简单的测试得出的结论,在这些例子中我的猜想得到证实,但不一定说明我的结论是正确的。如若有兴趣,希望我的方法能带来灵感。
欢迎大神批评指正。