• 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

基本语法

下文中所有...均为省略号,并不是正则表达式语法的一部分。

  1. JavaScript中用一对/定义正则表达式,var parse_url = /.../。 所以JavaScript正则表达式特殊的一点在于内容中的/需要转义为\/

  2. (...)用来创建一个捕获组(capturing group), 所有捕获组匹配的文本都会加入到结果数组中(regex.exec的结果,下标从1开始)。 所以匹配()需要转义:\(\)

  3. (?:...)用来创建一个非捕获组(non-capturing group), 仅仅是为了操作方便,匹配的文本不加入到结果数组中。

  4. [...]表示某个取值范围内的单个字符,比如[acd]匹配字母acd。 括号中的-是特殊字符,例如[a-e]相当于[abcde],当然要匹配特殊字符-需要转义: \-

  5. 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相关推荐

  1. php正则表达式判断url,判断url的正则表达式

    判断url的正则表达式判断url的正则表达式 @"^((https|http|ftp|rtsp|mms)?://)" + @"?(([0-9a-z_!~*'().& ...

  2. 截取url的host_java正则表达式获取url的host示例

    java正则表达式获取url的host示例 复制代码 代码如下: public static String getHost(String url){ if(url==null||url.trim(). ...

  3. C#分析URL参数获取参数和值得对应列表(一)

    C#操作Url参数 http://www.cnblogs.com/RobotH/archive/2008/11/17/1335322.html 用 C# 分析 URL 中的参数信息 http://ww ...

  4. android url 正则,正则表达式验证URL

    function IsURL(str_url){ var strRegex = "^((https|http|ftp|rtsp|mms)?://)" + "?(([0-9 ...

  5. php正则替换url,用正则表达式替换url参数

    这次给大家带来用正则表达式替换url参数,用正则表达式替换url参数的注意事项有哪些,下面就是实战案例,一起来看一下. 具体代码如下所示:/* 定义替换对象键值 */ var setReferArgs ...

  6. JAVA正则表达式分析爬虫数据

    网络爬虫与正则表达式 爬虫是爬取网络资源的一种重要途径,我们可以通过正则表达式来将所抓取到的数据进行分析,提取处所要得到的结果. 实验目标:抓取某一网站上所有的超链接 创建工具类,通过URL获得输出流 ...

  7. 大叔手记(16):分析URL Routing和URL Rewriting两者之间的不同

    前言 前面有2篇帖子提到了关于URL Routing的特性,但是发现有很多人误会URL Routing就是URl Rewriting,其实2个虽然都提供相似的功能(提高友好的URL方便搜索引起收录), ...

  8. Django基于正则表达式的URL

    1. 关于正则的说明 url(r'^detail-(\d+)-(\d+).html',views.detail), 当客户端输入 127.0.0.1:8000/detail-2-9.html时,Dja ...

  9. C++socket编程(七):7.4 正则表达式分析用户请求

    1.在实际的开发中用户访问一个姐买你可能有自己的具体操作.我们可以用C++自己的regex类包含的正则表达式的方式处理用户的请求. 如下代码: #include <stdlib.h> #i ...

最新文章

  1. Foundations of Qt Development 学习笔记 Part1 Tips1-50
  2. Linux内核网络中数据报在协议层的处理
  3. 推进大数据中心新能源应用 广东省六部门联合印发培育新能源战略性新兴产业集群行动计划(2021—2025年)...
  4. DROP TABLE、TRUNCATE TABLE和DELETE的区别
  5. 《Unit Testing》1.4. 成功的测试套件拥有哪些属性?
  6. imagestring不支持中文,改用imagettftext
  7. Error opening data file Tesseract-OCR\tessdata/eng.traineddata问题解决
  8. 科技公司 CEO 合谋“诈骗”自家公司超 900 万美元,现已被捕
  9. 国内博客(blog)搬家工具(服务)大全
  10. 数学分析—集合与映射
  11. win10 休眠设置无效_win10休眠设置无效的解决教程
  12. 生物什么时候学公式计算机,高考生物重要规律性关系及公式精华归纳,转走吧...
  13. 大脑中的CD19表达与CAR-T治疗关系
  14. 从零开始学JSON(修订版)
  15. HTML中的 meta 标签
  16. PPT2016;插入视频,无法实现自动播放
  17. 元宇宙虚拟人物风格形象应用场景制作
  18. 慕尼黑大学计算机语言学,慕尼黑大学,斯图加特大学和萨尔大学的计算语言学硕士如何选择?...
  19. laravel 使用workerman加速应用
  20. 20180629小测

热门文章

  1. 新的工作, 新的开始!
  2. 619300-53-7,DOTA-NOC,FC-2154,DOTA-NOC acetate,DOTA-[Nal3]-octreotide
  3. 华为5ipro详细参数使用功能_华为nova5i pro参数配置介绍 华为nova5i pro使用评测
  4. java数组和标准输入输出
  5. mysql 模糊查询like优化方案(亲测)
  6. 手机版明日之后无限法则服务器,《明日之后》安卓版服务器被挤爆,玩家吐槽网易没钱买服务器,对此你怎么看?...
  7. 敢问路在何方?国外安卓大神对Android原生开发现状剖析
  8. Ultimate Retouch Panel for Mac(PS磨皮插件)
  9. jq实现模糊搜索文本内容
  10. 雀魂服务器列表为空,GitHub - xieyuchen13/majsoulAI: 尝试基于雀魂数据训练日麻AI