用正则表达式分析 URL
- Slash(斜线)
- Host(主机名)
- Port(端口)
- Path(路径)
- Query(参数)
- Hash(锚点)
- 最佳实践
正则表达式是编程语言中非常重要的一部分, 虽然至今都未被正式引入到C++中,╮(╯▽╰)╭。 因为绝大多数编程语言都内置了字符串类型,编程实践中对字符串的匹配和操作也非常频繁。 而正则表达式在多数情况下都会更加高效,语法也更为简洁。 本文借分析URL的场景,详述JavaScript中正则表达式的基本语法和常用函数。
正则表达式有非常多不同的实现, JavaScript的正则表达式基本符合最初贝尔实验室的规则, 同时从Perl语言引入了一些有用的扩展。 正则表达式最难以让人接受的一点在于太难阅读和调试,不允许空白字符和注释。 当然这也是它迷人的地方,正因如此而非常简洁和高效。 正如Vim一般,你需要学习很多东西才能上手使用,但这些努力绝对值得。
代码
在Web开发中正则表达式一点都不陌生,在表单验证时一定会用到。 甚至在AngularJS中,ng-pattern
使用正则表达式增强了表单控件。 下面看一个正则表达式分析URL的例子:
var parse_url = /^(?:([A-Za-z]+):)?(\/{0,3})([0-9.\-A-Za-z]+)(?::(\d+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:#(.*))?$/;
var url = "https://harttle.land:80/tags.html?simple=true#HTML",result = parse_url.exec(url);blanks = ' ';fields = ['url', 'scheme', 'slash', 'host', 'port', 'path', 'query', 'hash'];
fields.forEach(function(field, i){console.log(field + ':' + blanks.substr(field.length) + result[i]);
});
上述代码的输出:
url: https://harttle.land:80/tags.html?simple=true#HTML
scheme: http
slash: //
host: harttle.land
port: 80
path: tags.html
query: single=true
hash: HTML
基本语法
下文中所有
...
均为省略号,并不是正则表达式语法的一部分。
JavaScript中用一对
/
定义正则表达式,var parse_url = /.../
。 所以JavaScript正则表达式特殊的一点在于内容中的/
需要转义为\/
。(...)
用来创建一个捕获组(capturing group), 所有捕获组匹配的文本都会加入到结果数组中(regex.exec
的结果,下标从1开始)。 所以匹配()
需要转义:\(
,\)
。(?:...)
用来创建一个非捕获组(non-capturing group), 仅仅是为了操作方便,匹配的文本不加入到结果数组中。[...]
表示某个取值范围内的单个字符,比如[acd]
匹配字母a
或c
或d
。 括号中的-
是特殊字符,例如[a-e]
相当于[abcde]
,当然要匹配特殊字符-
需要转义:\-
。x{3,8}
表示x
出现3到8次,闭区间。
下面几节便详细解释URL各部分的正则表达式。
Scheme(协议)
^(?:([A-Za-z]+):)?
匹配URL的协议。^
表示行首,这意味着ahttp
将不会被匹配。 接着是一个非捕获组,该组后面的问号表示该组可以出现1次或0次。
非捕获组的内容是一个捕获组加一个冒号:([A-Za-z]+):
,它匹配的结果是http:
。 捕获组的内容是[A-Za-z]+
,后面的+
表示至少出现一次,它匹配的结果是http
, 这是第一个捕获组,该结果被存到fields[1]
中。
fields[0]
中存放的是整个正则表达式匹配到的结果字符串,即整个URL。
Slash(斜线)
(\/{0,3})
匹配URL中协议后面的0到3个/
,因为/
是JavaScript正则表达式的定界符, 所以需要转义。匹配结果是//
,它也是一个捕获组,//
被存放到fields[2]
中。
Host(主机名)
([0-9.\-A-Za-z]+)
匹配主机名,它可以是数字,字母,点或横线。 匹配结果是harttle.land
,被存放到fields[3]
中。
Port(端口)
(::(\d+))?
匹配端口,结果是:80
。因为端口在URL中是可选的, 所以加?
表示可以出现0或1次。我们需要捕获的是不包括冒号的端口数字, 所以:(\d+)
被一个非捕获组括起来,\d+
是被捕获的(\d
表示单个数字)。 匹配结果是80
,被存放到fields[4]
中。
Path(路径)
(?:\/([^?#]*))?
匹配路径,其结果是/tags.html
。 外面还是一个可选的非捕获组,其内容为\/([^?#]*)
。 /
被转义为\/
,后面的内容[^?#]*
将被捕获,tags.html
被存入fields[5]
中。 [^...]
表示反相匹配,即不是?
和#
的任何其他字符, 因为?
表示URL参数部分的起始,#
表示页面锚点id的起始。
URL是有限字符集的,这样写是为了最大限度地容错。
Query(参数)
(?:\?([^#]*))?
匹配GET方法的参数,结果是?simple=true
。 还是一个可选的非获取组,其内容为\?([^#]*)
。 ?
是正则表达式中的特殊字符,所以需要转义。 后面匹配的结果simple=true
被存入fields[6]
中。 [^#]
表示#
之外的任何字符。
Hash(锚点)
(?:#(.*))?$
匹配锚点,结果为#HTML
。 $
表示行尾,即当前行所有内容都必须被前面的表达式所匹配。
前面是一个可选的非获取匹配,内容为#(.*)
。 .
表示任何单个字符,即#
开头的任何长度的字符串。 被获取的内容HTML
存入了fields[7]
中。
最佳实践
上文中的URL正则表达式略显复杂,在真实的实践中通常会切分为一系列的正则表达式单元。 为了实现正则表达式的拼接,我们需要定义一系列的字符串来初始化正则表达式。 这意味着需要做一些转义工作,费时费力事小,容易出错事大。例如上述Query参数:
var queryRegex1 = /(?:\?([^#]*))?/;
// 斜线都需要转义
var queryRegex2 = new RegExp("(?:\\?([^#]*))?");
好在JavaScript的RegExp提供了source
属性,可以帮我们转义正则表达式:
var queryRegex = /(?:\?([^#]*))?/;
queryRegex.source === "(?:\\?([^#]*))?";
var urlRegex = new RegExp(`...${queryRegex.source}...`);
本文采用 知识共享署名 4.0 国际许可协议(CC-BY 4.0)进行许可,转载注明来源即可: https://harttle.land/2016/02/23/javascript-regular-expressions.html。学识粗浅写作仓促,如有错误辛苦评论或 邮件 指出。
用正则表达式分析 URL相关推荐
- php正则表达式判断url,判断url的正则表达式
判断url的正则表达式判断url的正则表达式 @"^((https|http|ftp|rtsp|mms)?://)" + @"?(([0-9a-z_!~*'().& ...
- 截取url的host_java正则表达式获取url的host示例
java正则表达式获取url的host示例 复制代码 代码如下: public static String getHost(String url){ if(url==null||url.trim(). ...
- C#分析URL参数获取参数和值得对应列表(一)
C#操作Url参数 http://www.cnblogs.com/RobotH/archive/2008/11/17/1335322.html 用 C# 分析 URL 中的参数信息 http://ww ...
- android url 正则,正则表达式验证URL
function IsURL(str_url){ var strRegex = "^((https|http|ftp|rtsp|mms)?://)" + "?(([0-9 ...
- php正则替换url,用正则表达式替换url参数
这次给大家带来用正则表达式替换url参数,用正则表达式替换url参数的注意事项有哪些,下面就是实战案例,一起来看一下. 具体代码如下所示:/* 定义替换对象键值 */ var setReferArgs ...
- JAVA正则表达式分析爬虫数据
网络爬虫与正则表达式 爬虫是爬取网络资源的一种重要途径,我们可以通过正则表达式来将所抓取到的数据进行分析,提取处所要得到的结果. 实验目标:抓取某一网站上所有的超链接 创建工具类,通过URL获得输出流 ...
- 大叔手记(16):分析URL Routing和URL Rewriting两者之间的不同
前言 前面有2篇帖子提到了关于URL Routing的特性,但是发现有很多人误会URL Routing就是URl Rewriting,其实2个虽然都提供相似的功能(提高友好的URL方便搜索引起收录), ...
- Django基于正则表达式的URL
1. 关于正则的说明 url(r'^detail-(\d+)-(\d+).html',views.detail), 当客户端输入 127.0.0.1:8000/detail-2-9.html时,Dja ...
- C++socket编程(七):7.4 正则表达式分析用户请求
1.在实际的开发中用户访问一个姐买你可能有自己的具体操作.我们可以用C++自己的regex类包含的正则表达式的方式处理用户的请求. 如下代码: #include <stdlib.h> #i ...
最新文章
- Foundations of Qt Development 学习笔记 Part1 Tips1-50
- Linux内核网络中数据报在协议层的处理
- 推进大数据中心新能源应用 广东省六部门联合印发培育新能源战略性新兴产业集群行动计划(2021—2025年)...
- DROP TABLE、TRUNCATE TABLE和DELETE的区别
- 《Unit Testing》1.4. 成功的测试套件拥有哪些属性?
- imagestring不支持中文,改用imagettftext
- Error opening data file Tesseract-OCR\tessdata/eng.traineddata问题解决
- 科技公司 CEO 合谋“诈骗”自家公司超 900 万美元,现已被捕
- 国内博客(blog)搬家工具(服务)大全
- 数学分析—集合与映射
- win10 休眠设置无效_win10休眠设置无效的解决教程
- 生物什么时候学公式计算机,高考生物重要规律性关系及公式精华归纳,转走吧...
- 大脑中的CD19表达与CAR-T治疗关系
- 从零开始学JSON(修订版)
- HTML中的 meta 标签
- PPT2016;插入视频,无法实现自动播放
- 元宇宙虚拟人物风格形象应用场景制作
- 慕尼黑大学计算机语言学,慕尼黑大学,斯图加特大学和萨尔大学的计算语言学硕士如何选择?...
- laravel 使用workerman加速应用
- 20180629小测
热门文章
- 新的工作, 新的开始!
- 619300-53-7,DOTA-NOC,FC-2154,DOTA-NOC acetate,DOTA-[Nal3]-octreotide
- 华为5ipro详细参数使用功能_华为nova5i pro参数配置介绍 华为nova5i pro使用评测
- java数组和标准输入输出
- mysql 模糊查询like优化方案(亲测)
- 手机版明日之后无限法则服务器,《明日之后》安卓版服务器被挤爆,玩家吐槽网易没钱买服务器,对此你怎么看?...
- 敢问路在何方?国外安卓大神对Android原生开发现状剖析
- Ultimate Retouch Panel for Mac(PS磨皮插件)
- jq实现模糊搜索文本内容
- 雀魂服务器列表为空,GitHub - xieyuchen13/majsoulAI: 尝试基于雀魂数据训练日麻AI