URL 正则表达式

URL 正则表达式

在前端开发中,我们经常需要提取 URL 中的一些信息,例如域名、参数等等。这时候,我们就可以使用正则表达式来快速匹配 URL 中的各个部分。

URL 结构

一个标准的 URL 包含以下几个部分:

<scheme>://<user>:<password>@<host>:<port>/<path>?<query>#<fragment>
  • scheme 表示 URL 的协议,例如 httphttpsftp 等等。
  • userpassword 分别表示访问 URL 所需的账号和密码。
  • host 表示主机名,可以是域名或者 IP 地址。
  • port 表示端口号,默认为 80
  • path 表示 URL 请求的路径,可以包含多个层级的目录和文件名。
  • query 表示 URL 的查询参数,可以传递多个键值对,使用 & 分隔。
  • fragment 表示 URL 的锚点,用于页面定位跳转。

提取 URL 中的信息

提取域名

使用正则表达式提取 URL 中的域名,例如把 https://www.baidu.com/index.html 地址中的 www.baidu.com 提取出来。正则表达式如下:

const url = 'https://www.baidu.com/index.html';
const pattern = /^[^/]+\/\/[^/]+/;
const domain = url.match(pattern)[0];
console.log(domain); // https://www.baidu.com

我们使用正则表达式 ^[^/]+\/\/[^/]+,其中:

  • ^ 表示匹配行首。
  • [^/] 表示匹配除了 / 以外的任意字符。
  • + 表示匹配前面的字符 1 次或多次。
  • \/\/ 表示匹配 //
  • [^/]+ 同上。

注意,在提取出的域名后面应该加上 //,否则后面的请求会出错。

提取 URL 参数

我们经常需要在 URL 中传递参数,这时候可以使用正则表达式来获取这些参数。例如,把 https://www.baidu.com/search?q=javascript&sort=vote&page=2 地址中的参数提取出来。正则表达式如下:

const url = 'https://www.baidu.com/search?q=javascript&sort=vote&page=2';
const pattern = /\?(\S*)/;
const paramsStr = url.match(pattern)[1];
console.log(paramsStr); // q=javascript&sort=vote&page=2

我们使用正则表达式 \?(\S*),其中:

  • \? 表示匹配 ?
  • (\S*) 表示匹配非空白字符 0 次或多次,并用圆括号将结果捕获到分组中。

注意,取出分组中的参数字符串后,还需要进行进一步的处理,以便提取出每个键值对的具体信息。

提取 URL 中特定的参数值

在获取 URL 参数之后,有时候需要提取参数中特定键的值。例如,把 https://www.baidu.com/search?q=javascript&sort=vote&page=2 地址中的 q 参数提取出来。正则表达式如下:

const url = 'https://www.baidu.com/search?q=javascript&sort=vote&page=2';
const pattern = /q=([^&]*)/;
const value = url.match(pattern)[1];
console.log(value); // javascript

我们使用正则表达式 q=([^&]*),其中:

  • q= 表示匹配 q=
  • [^&]* 表示匹配非 & 字符 0 次或多次,并用圆括号将结果捕获到分组中。

注意,在进行正则匹配时,应该首先判断 URL 是否包含该参数,如果存在则再截取参数的值。

const url = 'https://www.baidu.com/search?q=javascript&sort=vote&page=2';
const paramName = 'q';
const pattern = new RegExp(`${paramName}=([^&]*)`);
const match = url.match(pattern);
if (match) {
  const value = match[1];
  console.log(value); // javascript
}

我们使用 RegExp 构造函数动态生成正则表达式,其中:

  • ${paramName} 表示插入变量 paramName 的值。
  • = 表示匹配 =
  • ([^&]*) 同上。

注意,在使用动态正则表达式时,要谨慎处理转义字符,确保最终生成的正则表达式是正确的。

URL 防御式编程

由于 URL 是由用户输入的,存在恶意用户输入攻击 URL 的风险,因此我们还应该进行防御式编程,避免代码被注入攻击。

URL 校验

首先,我们需要对用户输入的 URL 进行校验,确保 URL 的合法性。可以使用正则表达式来验证 URL。

const url = 'https://www.baidu.com/index.html';
const pattern = /^(http|https|ftp):\/\/[\w\-]+(\.[\w\-]+)*([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?$/;
if (pattern.test(url)) {
  console.log('URL is valid.');
} else {
  console.log('URL is invalid.');
}

我们使用正则表达式 ^(http|https|ftp):\/\/[\w\-]+(\.[\w\-]+)*([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?$,其中:

  • ^ 表示匹配行首。
  • (http|https|ftp) 表示匹配 httphttpsftp
  • :\/\/ 表示匹配 ://
  • [\w\-]+ 表示匹配字母、数字、下划线、连字符,至少匹配 1 次。
  • (\.[\w\-]+)* 表示匹配.后面跟字母、数字、下划线、连字符,至少匹配 0 次(即可以没有)。加上圆括号表示可以匹配多个这样的字符串。
  • ([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])? 表示匹配 URL 路径和查询参数部分。
  • $ 表示匹配行尾。

注意,该正则表达式可以过滤掉一些字符,但并不能完全消除恶意攻击,因此需要进行进一步的防御。

URL 编码和解码

由于 URL 中可以包含一些特殊字符,而浏览器对这些字符的解释不一定相同,因此我们需要对 URL 进行编码和解码,以保证浏览器的解释结果一致。

// 编码
const url = 'https://www.baidu.com/search?q=javascript&sort=vote&page=2';
const encodedUrl = encodeURI(url);
console.log(encodedUrl); // https://www.baidu.com/search?q=javascript&sort=vote&page=2

// 解码
const decodedUrl = decodeURI(encodedUrl);
console.log(decodedUrl); // https://www.baidu.com/search?q=javascript&sort=vote&page=2

我们使用 encodeURIdecodeURI 方法对 URL 进行编码和解码,其中:

  • encodeURI 方法可编码 URL 中除字符 A~Z a~z 0~9 - _ . ! ~ * ' ( ) ; : @ & = + $ , / ? # [ ] 以外的所有字符,编码后的字符使用 % 加 ASCII 码的 16 进制表示,例如空格编码后为 %20
  • decodeURI 方法可解码 encodeURI 编码的字符。

注意,在进行 URL 编码和解码时,应该谨慎处理字符串中包含的特殊字符,确保最终的编码和解码结果是正确的。

总结

本文介绍了如何使用正则表达式来提取和处理 URL 中的各个部分,以及如何进行防御式编程来避免恶意攻击。正则表达式是前端开发的基础技能之一,能够帮助我们快速解决很多问题,但也需要注意正则表达式的使用风险,并进行进一步的防御。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程