一个匹配URL的正则表达式例子(带详细解释)

时间:2022-03-09 06:56:31

可处理正则表达式的方法有regexp.exec、regexp.test、string、match、string.replace、string.search和string.split。正则表达式相较于等下的字符串处理有显著的性能优势。

举个例子:下面是一个匹配URL的正则表达式(注意JavaScript中正则表达式必须写在一行中,由于浏览器窗口大小有限这里可能会显示为两行):

var parse_url = /^(?:(A-Za-z+):)?(\/{0,3})([0-9.\-A-Za-z]+)(?::(\d+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:#(.*))?$/;

接下来调用parse_url的exec方法。如果能成功匹配传给它的字符串,就会返回一个数组,该数组包含了从这个url中提取出来的片段:

var url = 'http://www.bbc.com:8088/goodparts?q#fragment';
var result = parse_url.exec(url);
var names = ['url','scheme','slash','host','port','path','query','hash'];
var blanks = ' ';
var len = names.length;
var i;

for(i=0; i < len;i += 1) {
document.writeln(names[i] + ':' + blanks.substring(names[i].length), result[i]);
}

上面这段代码产生的结果如下:

url:  http://www.bbc.com:8088/goodparts?q#fragment 
scheme: http
slach: //
host: www.bbc.com
port: 8088
path: goodparts
query: q
hash: fragment

分解parse_url的各个部分,看它是怎么工作的:

^

^字符表示此字符串的开始。它是一个锚,指引exec不要跳过那些不像URL的前缀,只匹配那些从开头就像URL一样的字符串;

(?:(A-Za-z)+):)?

这个因子匹配一个协议名,但仅当它后面跟随一个 : (冒号)的时候才匹配。(?: …) 表示一个非捕获型分组。后缀 ? 表示这个分组是可选的。它表示重复0次或者1次。( … )表示一个捕获型分组。一个捕获型分组会复制它所有匹配的文本,并把其放到result数组里。每个捕获型分组都会被指定一个编号。第一个捕获型分组的编号是1,所以该分组所匹配的文本副本会出现在result[1]中。[ … ]表示一个字符类。A-Za-z这个字符类包含26个大写字母和26个小写字母。连字符( - )表示范围从A到Z。后缀 + 表示这个字符类会匹配一次或多次。这个组后面跟着字符 : ,它将会按照字面进行匹配;

(\/{0,3})

下一个因子是捕获型分组2。\ /表示应该匹配 / (斜杠)。用 \ (反斜杠)来进行转义,就不会被错误地理解为这个正则表达式的结束符。后缀{0,3}表示 / 会被匹配0次,或者1-3次;

([0-9.\-A-Za-z]+)

下一个因子是捕获型分组3。它会匹配一个主机名,由一个或者多个数字、字面,以及 . 或 - 字符组成。- 会被转义为 \ -以防与表示范围的连字符混淆;

(?::(\d+))?

下一个可选的因子匹配端口号,它是一个前置 : 加上一个或者多个数字而组成的序列。\d表示一个数字字符。一个或者多个数字组成的数字串会被捕获型分组4捕获;

(?:\/([^?#]*))?

接下来的可选的分组以一个 / 开始。之后的字符类[^?#]以一个^开始表示这个类包含除 ? 和 # 之外的所有字符。 * 表示这个字符类会被匹配0次或多次;

(?:\?([^#]*))?

接下来是一个以 ? 开始的可选分组。它包含捕获型分组6,这个分组包含0个或多个非 # 字符;

(?:#(.*))?

最后一个可选分组是以 # 开始。 . 会匹配除行结束符以外的所有字符。

$

$表示这个字符串的介绍。它保证在这个URL的尾部没有其他内容了。
以上便是正则表达式parse_url的所有因子。