【转】刨根究底正则表达式(1):开篇

奇葩的正则表达式

1、常规学习过程很痛苦

计算机领域中有一些非常基础、重要以及应用广泛,但却又特别容易让人困惑、非常难以理解的主题,这包括了字符编码、字节序(即大小端表示)、浮点数实现、日期时间处理以及正则表达式等。

正则表达式目前市面上并不缺乏专业著作,比如那本被誉为正则表达式学习圣经的《精通正则表达式》就很值得一读,另外该书的译者余晟先生所写的《正则指引》也不错。

如果仅用于入门,则《正则表达式必知必会》肯定不能错过,还有网上流传极广的《正则表达式30分钟入门教程》也是不错的入门资料。

但是,结合我自身痛苦的正则表达式学习经历和运用体会,仅有这些是远远不够的。

记得被大家称之为“轮子哥”的大神级程序员vczh在知乎上说过,当初被正则表达式虐得一气之下,干脆自己写了一个正则引擎(源码托管在Github上),才算真正彻底搞懂正则表达式(于是被戏称为“一言不合”就造轮子)。

当然不是每个程序员都能像“轮子哥”这样生猛,但即便都有这么生猛,似乎也没必要都像他一样自己花费大量时间再造一个正则引擎的“轮子”。

那到底应该怎样才能最高性价比(主要是最高时间-成本比)地掌握正则表达式这个神器呢?

2、一旦用过了再也回不去的“神器”

正则表达式是典型的那种你没用过的话,不觉得对自己有什么影响,可是一旦用过了,就再也回不去了的“神器”。

当然,我这里所说的“用过”,不是指简单地会用一些基本功能,而是指能够熟练地运用正则表达式的基本功能和高级功能。只要你用得越熟练,你就会越惊叹于其高效、强大与神奇。

看到这里,我相信某些接触过正则表达式、会使用一些基本功能的童鞋,心里或许在犯嘀咕了:神器是神器,可这玩意儿看起来就像天书一样,也太难学、太难懂了,要达到熟练运用的程度,谈何容易!

短短的一个正则表达式,或许不到10个字符,其中的每个字符都认识,但它们连在一起,却让人越看越迷惑,越想越迷糊……

其实,这正是我学习正则表达式时的真实心情。

是的,正则表达式既然被捧上了神器级别的高度,自然是有着相当强大的功能,而强大的功能就意味着其有非常深厚的内涵,也就意味着有很多需要注意的细节。

3、关键在于掌握其独特的“性格”和“脾气”

注意,我这里并没有说正则表达式是由于复杂而难以理解,这是因为,深厚的内涵不等于复杂,细节很多不意味着难以理解。

看到这里,或许有人有意见了,正则表达式还不算复杂?还不够难理解?

其实,我真正想说的是,繁复或许是真的,杂乱倒未必。因此,简单地说正则表达式复杂,似乎不够准确而客观。

正如跟一个牛叉而又性格独特的人打交道,关键不在于纠结其性格的独特、脾气的古怪,而是重在充分了解并理解其独特的性格、古怪的脾气,然后在此基础上与Ta进行良好的沟通,以便能好好发挥其牛叉之处。

学习并熟练掌握正则表达式的过程也是如此——关键在于先要摸透其“性格”到底独特在哪里,其“脾气”又究竟古怪在何方。一旦摸清楚了其“性格”,其“脾气”,学习起来就事半功倍了。

因此,我下面准备从我自己的角度,先尝试着来分析一下正则表达式那独特的“性格”与古怪的“脾气”,看看究竟为什么正则表达式给那么多人的感觉都是那么难以“亲近”。

正则表达式为什么这么难?

1、高度简洁、高度抽象是难学的关键

正则表达式有一个非常明显的特点:高度简洁、高度抽象。正则表达式中短短的几个字符,或许就代表了一段复杂的处理逻辑和匹配算法。

我们知道,程序代码是对现实事务处理逻辑的抽象,而正则表达式则是对复杂的字符匹配程序代码的进一步抽象;也就是说,高度简洁的正则表达式,其背后所对应的是字符匹配程序代码,而字符匹配程序代码,背后对应的是字符匹配处理逻辑。

因此可以这么认为,字符匹配处理逻辑,抽象为字符匹配程序代码;字符匹配程序代码,再进一步抽象为高度简洁的正则表达式。

所以说,高度简洁的正则表达式也是高度抽象的。

2、其他难学的原因

当然,正则表达式之所以难学、难理解,除了由于正则表达式具有高度简洁、高度抽象的特点之外,大致上应该还有以下几个原因:

1)学习者不求甚解,不了解正则引擎内部的基本原理

作为正则表达式的使用者,不需要深入了解正则引擎内部原理的技术实现细节,那是正则引擎开发者更应该了解的;但若完全不了解其基本工作原理和运行机制,也是不足取的。

2)有多个多义元字符,特别容易使人混淆、迷乱

比如-、+、?、^,尤其是元字符?,既可以作为量词表示其所限定的子表达式为可选(即匹配0次或1次),也可以置于量词之后表示懒惰匹配,而且还有很多特殊分组结构中用到它。

比如(?<name>sub-regex)(?:sub-regex)(?>sub-regex)(?=sub-regex)(?!sub-regex)(?<=sub-regex)(?<!sub-regex)(?|sub-regex)(?modifier-modifier)(?(condition)|)(?R)(?num)(?#comment)等。

还记得我自己当初刚开始学习的时候,一看到正则表达式中的问号?,就有一种独自在风中凌乱的感觉。

3)转义也是难点

什么情况下需要转义,什么情况下不需要转义,貌似复杂得令人抓狂。

当然,其实是有一定的规律的,掌握了这些规律,再遇到转义问题,就不至于心潮澎湃了。

4)学习期望与学习方法不对

不应该期望一次性记住、学会并熟练运用,正确的学习姿势应该是先简单入门,对一些基本的规则与元字符大致了解一遍,有个印象就好,在需要时再回过头来看,不用刻意去强行记忆。

然后接下来就是在工作中多实践、多运用,边学、边深入、边熟练。

5)有用于入门的好教程、备忘单,也有用于深入的大部头专著,但却缺乏好的速查手册

由于需要边学、边深入、边熟练,因此,平时手头边更需要的不是简单的入门教程、备忘单(Cheat Sheet),也不仅仅是知识点分散于各处的大部头专著(知识点分散导致查找起来不方便,用于深入学习原理是不错,但不够实用),而是一本速查手册。

速查手册按语法元素将知识点综合在一起进行编排的、在需要回过头来看时能够随时快速翻查。

这样,在实践运用中遇到问题就可方便随时快速翻查,而这一点恰恰对于正则表达式这种不可能短期内快速掌握并熟练运用的专业工具的学习与使用非常重要。

6)没有使用好的学习工具

你知道regex101.comregexper.comRegexBuddy等正则表达式的专业网站和专业工具吗?

这些堪称学习正则表达式的神器,可令学习事半功倍,但很多人不知道,或知道但很少使用。

什么才是更好的学习姿势

1、从两个不同的角度和维度来看

对于正则表达式的分析和解读,目前大多数文章和书籍多集中在正则表达式自身,比如对正则表达式的各个元字符、元转义序列以及匹配原理的分析和解读上。

当然,这些自然也是很有必要的,而且是学习的主要内容,是理解正则表达式所必需的。然而,很多人在看了大量这类文章和书籍之后,仍然觉得正则表达式很难看懂,不好理解。

难道就没有更好的学习姿势了吗?

其实,理解一个事物,往往可以有不同的角度和维度。多个角度和多个维度相结合,对于事物的理解可以更为深入,而且经常还会有“原来如此”这样豁然开朗的畅快感。

下面是我理解一个事物通常所用到的两个不同的角度和维度:

一是,深入事物本身去理解它内在的原理和机制等底层逻辑; 二是,跳出事物本身,站在一个更高的维度和层面,横向地与其他同类事物进行比较,纵向地去分析它的发展与演变。

正如苏轼那首著名的哲理诗《题西林壁》所说的,“不识庐山真面目,只缘身在此山中”。很多时候往往就是这样,当你只从该事物本身来看的话,就如在云里雾里,是远远不够的。

而一旦跳出到该事物之外,站在更高的一个维度来看,则又正如王安石的《登飞来峰》中所说:“不畏浮云遮望眼,只缘身在最高层”,登高望远,则一览无余了。

2、刨根究底正则表达式的根源和本质

对正则表达式而言,前者正是目前大多数文章和书籍在做的;而后者,却很少有文章和书籍能够跳出正则表达式,站在更高的维度或层面来分析和解读正则表达式。这里就包括了《精通正则表达式》和《正则指引》两书。

这里需要特别强调一下的是,我绝没有贬低上述这两本专著及其作者和/或译者之意,而且恰恰相反,这两本专著正是本系列文章的重要参考书。尤其无论是作为《精通正则表达式》的译者,还是作为《正则指引》的著者,余晟先生都得上是专业而又严谨的。

即便是对于前者而言,目前大多数文章和书籍也多半是一上来就正则表达式本身来说正则表达式,而往往没有去深挖正则表达式背后的根源和本质。

从根源上来讲,正则表达式是为了解决一个基本问题——文本的查找问题(也称为匹配问题);从本质上来讲,正则表达式也是一门编程语言,并且具有典型的编程范式。

当然,正则表达式的功能除了查找文本之外,还包括提取、验证、替换、切分文本等,但这些功能都是在查找文本功能基础上衍生出来的。

然而文本查找问题的解决方案有其历史演变的过程,只有理解了该过程,以及将正则表达式放在该历史过程的背景上,才能更好、更彻底地理解正则表达式。

而站在正则表达式也是一门编程语言的角度,如果能够从纵向编程语言发展史和横向编程范式的角度来看正则表达式,则会有高屋建瓴、纲举目张之感。

后面的文章,我会先从文本查找功能的历史演变过程讲起,随后再从编程语言发展史角度来看看正则表达式到底是一门怎样的语言,以及具有什么典型的编程范式。

然后,在此基础上,再来深入学习正则表达式,我相信,你一定会有跟以往完全不一样的感觉和理解。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/437477.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

正则表达式:匹配非0的整数和小数Double

要求可以是整数、小数&#xff0c;但是不能为0 下面正则0.0之类的也是匹配不中的 (后来测试发现出一个bug&#xff0c;竟然可以匹配到1 1&#xff0c;中间加个空格可以匹配中) ^(([1-9][0-9]*.{1}[0-9])|([0].{1}[1-9][0-9]*)|([1-9][0-9]*)|([0][.][0-9][1-9]))$所以又改了一…

【转】刨根究底正则表达式(2):文本查找方式的演化历史

上一篇文章讲到&#xff0c;从根源上来讲&#xff0c;正则表达式是为了解决文本的查找问题(也称为匹配问题)而诞生的。不过&#xff0c;文本查找方式的历史&#xff0c;要远早于正则表达式。 那么&#xff0c;在正则表达式出现之前&#xff0c;文本查找方式经历了什么演化过程…

正则表达式: input框禁止输入空格:不能只有空格、不能有空格、不能为空的判断

1.只有中间和最后能输入空格(如果让最后不能输入空格则把最后一个*改成)&#xff0c;(如果想让开头可以输入空格则把改成*) ^[^\s][\s]*.*$2.不能输入空格 ^[^\s]*$3.如果也不能为空(我是用required来判断的),把*改成 &#xff08;具体我没测试&#xff0c;感觉可以&#xff…

台式机电脑配置单_2020年电脑配置单重点硬件参考

&#xff0c;电脑的基本配件扫盲我前面写过很多&#xff0c;相信很多小伙伴都看过了&#xff0c;没有看过的可以上我专栏参观&#xff1a;电脑神棍局-组装机专栏​www.zhihu.com配置单在本文后面两篇&#xff0c;但是建议前面花两分钟看下。游戏篇后续还有工作和视频工作站篇主…

【转】刨根究底字符编码之五——简体汉字编码方案(GB2312、GBK等)以及全角、半角、CJK

一、概述 1. 英文字母再加一些其他标点字符之类的也不会超过256个&#xff0c;用一个字节来表示一个字符就足够了(2^8 256)。但其他一些文字不止这么多字符&#xff0c;比如中文中的汉字就多达10多万个&#xff0c;一个字节只能表示256个字符&#xff0c;肯定是不够的&#…

正则表达式:匹配Double类型,整数和小数

正则表达式:匹配Double类型&#xff0c;整数和小数 ^(([0])|([1-9][0-9]*.{1}[0-9])|([0].{1}[1-9][0-9]*)|([1-9][0-9]*)|([0][.][0-9][1-9]))$

开机cpu风扇声音大_联想拯救者R720笔记本,开机显示暗屏,二修机多故障完美修复...

【机器型号】拯救者R720-15(7代I5)【主板版号】NM-B191【故障现象】笔记本不开机接同行送修笔记本拯救者R720-15&#xff0c;7代I5的机器&#xff0c;同行描述说不开机。【维修过程】 拿到机器按下开关没反映&#xff0c;三下五除二&#xff0c;扒下这台电脑的衣服&#xff0c;…

【转】刨根究底字符编码之六——简体汉字编码中区位码、国标码、机内码、外码、字形码的区别及关系

GB2312、GBK、GB18030等GB系列汉字编码方案的具体实现方式是怎样的&#xff1f;区位码是什么&#xff1f;国标码是什么&#xff1f;内码、外码、字形码又是什么意思&#xff1f;它们是如何转换的&#xff0c;又为什么要这样转换&#xff1f; 下面以GB2312为例来加以说明。 一、…

正则表达式:日期格式的校验(日期+时间)

日期格式如下&#xff1a;2020-09-25 00:00:00&#xff0c;并且中间-是可以省略的&#xff0c;那么我们到了后台就需要将时间给转换回来 ^((\d{2}(([02468][048])|([13579][26]))[\-]?((((0[13578])|(1[02]))[\-]?((0[1-9])|([1-2][0-9])|(3[01])))|(((0[469])|(11))[\-]?(…

公共链接url出错_SEO优化技巧:关于URL的优化方法

点击标题下「蓝色微信名」可快速关注URL优化需要遵循一些原则&#xff0c; 采用以下方法&#xff0c;网页的用户体验更佳&#xff0c;同时对搜索引擎更友好。01URL越短越好对于搜索引擎来说&#xff0c;只要URL不超过265Byte&#xff0c;收录就没有问题。如果使用几百个字母的U…

【转】刨根究底字符编码之七——ANSI编码与代码页

一、ANSI编码 1. 如前所述&#xff0c;在全世界所有国家和地区的文字符号统一编码的UCS/Unicode编码方案问世之前(UCS、Unicode后文有详细介绍)&#xff0c;各个国家、地区为了用计算机记录并显示自己的字符&#xff0c;都在ASCII编码方案的基础上&#xff0c;设计了各自的编…

Angular 下拉搜索框实现

今天有个需求要写一个下拉搜索框&#xff0c;本来是下拉框的&#xff0c;由于内容太多&#xff0c;所以添加一个查找功能。根据博客进行改写的。参考了他的基本框架进行实现。 效果图&#xff1a; 输入框右边的白色箭头图片下载地址 <td>xxxxxxx</td> <td sty…

新手前端练手网站_编程到底难不难学?新手入门选择哪种语言好?

以下内容适合的读者&#xff1a;想要学习编程的小白一.编程到底难不难学&#xff1f;对于这个问题我的回答是不知道&#xff0c;学会了编程的人会说好学&#xff0c;中途就放弃的人会说很难&#xff0c;任何知识想要掌握好都不是一件容易的事情。所以我决定用自己的实际行动来证…

【转】刨根究底字符编码之八——Unicode编码方案概述

Unicode编码方案概述 1. 前面讲过&#xff0c;随着计算机发展到世界各地&#xff0c;于是各个国家和地区各自为政&#xff0c;搞出了很多既兼容ASCII但互相之间又不兼容的各种编码方案(微软统一称之为ANSI编码&#xff0c;具体体现为各种ANSI代码页)。 这样一来&#xff0c;同…

Angular 自定义属性指令-禁止input框输入空格-以及删除复制内容中的空格

创建一个ts文件&#xff0c;并在module.ts中定义 import { Directive, ElementRef, HostListener, Input } from angular/core; import { FormGroup, FormControl, NgControl } from angular/forms; Directive({selector: [input-noSpace]}) export class NoSpace {constructo…

基于androidx的快速开发框架_Vue企业级优雅实战07框架开发03封装基于MockJS的模拟数据...

预览本文的实现效果&#xff1a;# giteegit clone gitgitee.com:cloudyly/dscloudy-admin-single.git# githubgit clone gitgithub.com:cloudyly/dscloudy-admin-single.gitgit checkout 05_MockJS本文主要内容&#xff1a;基于 Mock JS&#xff0c;优雅设计网络请求的模拟数据…

【转】Net Framework,Net Core 和 Net Standard 区别

前几天我在一个群里看到有关这方面的讨论&#xff0c;最后感觉讨论的不是很清晰&#xff0c;有幸的是我们的项目去年就开始迁移NetCore的调研了&#xff0c;我个人多多少少也是有过这方面的研究。下面我将说一下我自己对着三个的认识如果有不足的地方&#xff0c;请大家指出。 …

记录一次SQL优化,增加索引,随便写的当笔记了

写了一个SQL&#xff0c;前端往返时间大约1.7秒&#xff0c;最终优化到一共150毫秒左右&#xff0c;应该还可以更好一些 下面说的有点乱&#xff0c;有空再好好总结一下吧。参考文章里面写的还是比较好的&#xff0c;只不过没有组合查询。 参考链接&#xff1a;https://zhuan…

使用函数求最大公约数 pta_高中数学选修教材2-导数第6课时《函数的单调性与导数》教学设计...

选修2-2第一章1.3.1 函数的单调性与导数一、先复习一下&#xff0c;上节课讲到了利用导数求曲线的切线方程(点我)&#xff0c;咱们这节课接着讲利用导数判断函数的单调性。二、做出图像形象生动&#xff0c;让学生看到当斜率为正(亦是导数为正)的时候函数图像是上升的&#xff…

Kafka幂等性与事务

kafka幂等性 博客https://www.cnblogs.com/smartloli/p/11922639.html 幂等性&#xff1a; 主要解决单会话&#xff08;producer宕机重启幂等性失效&#xff09; 主要是引入了ProducerID和SequenceNumber来实现幂等性 &#xff0c;当producer发送消息给broker后等待返回ack&…