Skip to content

正则表达式解析URL #22

@shimuash

Description

@shimuash
var url = "https://www.example.com:80/user?query#hash"

var parse_url = /^(?:([A-Za-z]+):)?(\/{0,3})([0-9.\-A-Za-z]+)(?::(\d+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:#(.*))?$/g
var names = ['url', 'scheme', 'slash', 'host', 'port', 'path', 'query', 'hash']
var res = parse_url.exec(url)
names.forEach(function (name, index) {
  console.log(name + ' : ' + res[index])
})

// "url : https://www.example.com:80/user?query#hash"
// "scheme : https"
// "slash : //"
// "host : www.example.com"
// "port : 80"
// "path : user"
// "query : query"
// "hash : hash"

分析

^

^字符表示此字符串的开始

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

这个因子匹配一个协议名。当它后面有个:时才匹配。(?: ....)表示一个非捕获型分组。
后缀?表示这个分组时可选的,表示重复0次或者1次。(...)表示一个捕获型分组,
捕获型分组会复制它所匹配的文本,并把它放在result数组中。每个捕获型分组都会被指定一个
编号。第一个捕获型分组的编号是1,所以该分组所匹配的文本副本会出现在result[1]中。
[...]表示一个字符串。A-Za-z这个字符类包含26个字母的大小写。后缀+表示这个字符类
会被匹配一次或者多次

(\/{0,3})

捕获分组2,\/表示应该匹配/\用来转义。后缀{0,3}表示/会被匹配0次或者1~3次

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

捕获分组3,匹配一个主机名,由一个或多个数字、字母,以及.-字符组成

(?::(\d+))?

捕获分组4,匹配端口号,由一个前置:加上一个或多个数字组成的序列。
\d表示一个数字字符

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

捕获分组5,该分组以/开始。[^?#]以一个^开始,表示这个类包含除?#之外的所有
字符。*表示这个字符会被匹配0次或者多次

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

捕获分组6,以?开始的可选分组,包含0个或多个非#字符

(?:#(.*))?

捕获分组7,以#开始的可选分组,.会匹配除行结束符以外的所有字符

$

结束字符

解析查询参数

function queryTobject (url) {
  var query = url.substring(url.indexOf('?') + 1)
  var reg = /([^?&=]+)=([^?&=]*)/g
  var obj = {}
  query.replace(reg, function (rs, $1, $2) {
    var name = decodeURIComponent($1)
    var val = decodeURIComponent($2)
    obj[name] = val
    return rs
  })
  return obj
}

经过一段时间的学习,正则表达式总算有点熟悉了,可以读懂一些常用的表达式。

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions