程序员眼中的正则表达式

写程序时,很多时候就是在跟字符串打交道,用户输入的内容是字符串, 响应用户的输出也是字符串。 假如程序是基于http的web应用, 那所有动态的数据除了多媒体数据以外都由字符串构成,url是字符串, html/xml是字符串,json是字符串,http请求首部和请求体也都是字符串。 网站, 就是一种由字符串统制的程序。处理字符串普遍用到两种方式,一种就是普通的字符串处理函数,如split切割,replace替换,join连接,substr取子串等。还有一种方式就是利用「正则表达式」。开发人员在碰到处理字符串的问题时, 首选方案是通字符串处理函数来帮助完成任务, 当碰到一些字符串处理函数无法胜任的复杂效果时, 才会祭出正则表达式这把利器。 然而, 这把利器不是这么容易使的, 使的好,可以干净利落的完成任务;使的不好, 能把自己手给割了。为保险起见,一部份程序员会这样的使用正则表达式。

打开搜索引擎,输入“把字符串中的html替换掉的正则表达式怎么写”,“url重写分页正则表达式怎么写”,“匹配邮箱地址的正则表达式”,“匹配网址的正则表达式”等关键字进行搜索。

如果碰到的问题太过于具体, 网上找不到可参照的案例,就只能上一些技术论坛提问,或者寻找他人帮忙解决。

当然,也可以寻找非正则解决方案替代,然而, 这将大费周章。

这其中部份的原因是因为相当大一部份程序员对正则的掌握是比较薄弱的。程序员看待技术一般分为两个层面, 首先是饭碗,其次是兴趣。 某一些技术是饭碗级别的,掌握不好意味着行业内失去境争力, 甚至失业。不会数据库的Web程序员和不会JavaScript前端开发, 基本上是废的。因此, 程序员们为了保住 自己的饭碗, 会不遗余力的去钻研饭碗级别的技能。正则表达式,并不属于饭碗级别的技能,除非是有特殊需求,否则公司招聘程序员, 不会把正则表达式作为必要的技能指标。 这导致了程序员学习正则表达式动力的不足,只有小部分程序员会因为兴趣而去学习。此外,正则看似是一个嵌入在编程语言中的小部件,仿佛是属于语言的一个组成部份,然而,真正能灵活使用它不但需要掌握非常多的基础概念, 还需要反复的实践锤炼,这是一个系统的学习过程, 难度不亚于掌握一门全新的编程语言。似乎由于学习成本和所得回报之间的比例不协调, 使得只有很少一部份程序员愿意系统全面的学习这门技术。

从表面上看,正则表达式是处理字符串的一条捷径,在实际应用中属于锦上添花的功能。其实, 利用正则抄近路和通过普通程序的绕远路就如同坐电梯和爬楼梯,咋一看似乎可以接受, 但是, 如果让你爬到一百层大厦的顶层或者你在上班迟到的边缘还让你爬楼梯。正则表达式的作用就体现在这里, 它在处理一些极端的编程问题上能发挥巨大的威力。写程序的首要任务就是逻辑的组织,程序越是理的井井有条, 就越容易高效正确的解决问题, 正则表达式正是将一系列复杂的字符串处理逻辑集中在一个短小精悍的表达式之内,逻辑的真正执行过程却由正则引擎代劳,而不用我们手动编码实现, 这使程序整体的逻辑更加清晰简单流畅。在合适的编程场景中正确的使用一个正则表达式会让你有一种打俄罗斯方块时利用长度为N层的钢管消除N层方块的快感。特别的, 对于经常编写linux shell的程序员来说, 正则表达式的价值将更能体现。linux命令的间的结果就是以字符串来传递的, 因此,能利用正则表达式来解决问题的机会也会高于开发其它类型程序,这意味着,合理利用正则表达式, 能大大的提高在linux下的工作效率。

讲两个案例, 分析一下正则表达式是如何处理实际工作中的问题的

刚在前几天,公司需要在一台windows server上部署一个跑在tomcat上的java网站。因为是windows server,所以优先选择IIS作为网站的前端代理, 将请求转发至后端tomcat来进行处理, 这里的IIS就扮演着一个和nginx一样的角色。匹配转发至 tomcat的处理的url的正则表达式是^(.*), 这个正则能匹配所有的字符串,换句话说就是IIS接受到的所有请求都 转发给后端的tomcat来处理,除了 动态的servlet链接外, 所有的静态资源,像图片、js、css请求都转发给了tomcat。显然,这不是tomcat擅长的。 正确的方案应该是所有静态资源由IIS处理,动态servlet请求由IIS转发至tomcat处理。IIS应该支持这样的功能配置,然而, 我并不知道怎么搞, 也不愿意花精力去网上搜索答案 。于是我想通过修改正则表达式的方式来实现这个功能, 之前那个正则表达式所表达出来的逻辑是「匹配任何url」,现在需要把逻辑修改成「匹配所有不带文件扩展名的url和带.jsp扩展名的url」,这样就能把所有静态资源排除在外了,于是我把正则表达式修改为^(([^\/]*\/)+(([^\/\.]+\/?$)|(\w+\.jsp[^\.]*$))),也许这不能算标准或完美的解决方案,但胜在快捷,把去网上找其他的配置方案的时间和再做进一步配置的功夫节省了下来。

另一个案例是在去年, 公司运营有需求需要让一套系统支持多国语言, 且可以动态切换。 这就意味着,需要将项目中所有的中文字符串提取出来,制作成语言包,之后还需要在此基础上进行扩展,增加英文或其他国家的语言包。项目包含几百个文件, 几万行代码,如果是纯手动来完成这项任务,不但枯燥乏味,而且浪费时间。于是我捉摸着可以使用程序自动化来完成这项工作, 首行想到的是利用代码的静态分析技术来解决,只是提取中文这符串的话可以实现一个静态分析的阉割版, 然而, 就算是阉割版, 也还是过于复杂。 第二种方法是直接把代码中符合要求的字符串抓出来,并以程序变量替换,以实现语言包的功能。这个时候正则表达式正好有了用武之地,以字符串的形式分析每一行代码,利用正则表达式将符合要求的结果提取出来,制成语言包。语言包提取程序的实现只花了两天不到的时候,而且成果对于其它项目也适用, 换言之就是如果其它项目也需要支持多语言包切换功能, 可以直接把这个语言包提取程序拿过去用,解放双手。

在工作的这些年中, 利用正则表达式巧妙解决问题的案例多不胜数,不过在这里多写也没有意义 。如果想加强自己解决问题的能力,提升工作效率 , 正则表达式绝对是一把不可多得的神器。掌握它, 对工作的帮助并不会有立竿见影的效果,然而, 在工作中的某个时刻,它会冷不丁的给你一种「这项技术我真的没有白学」的感受。

在这里就不介绍正则表达式的技术细节的,只粗略的说一下学习的方法。想要全面是掌握正则表达式, 首先需要掌握以下几个核心概念

  • 优先匹配
  • 忽略优先匹配
  • 环视
  • 回溯

掌握这四个概念等于掌握正则的核心运行原理, 这相当于一坐桥的桥墩, 桥墩不扎实, 过桥的车也可以把桥给压塌了。剩下的就是一些较为容易理解的概念或细节, 一般通过搜索引擎就能找到运用的方法, 相对于前面几个核心概念, 这些内容并非一定需要系统的学习(能系统的学习最好)。

最后,推荐一本书《精通正则表达式》,此书通谷易懂的将正则表达式事无巨细的描述了一遍,是学习正则表达式的权威之作,也是我看过第二受用的一本书

原文发布于微信公众号 - 带你撸出一手好代码(gh_afab56b37671)

原文发表时间:2016-09-20

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏机器学习算法与Python学习

Python高居顶级编程语言交互排行榜第一,你要做些什么呢?

关键字全网搜索最新排名 【机器学习算法】:排名第一 【机器学习】:排名第二 【Python】:排名第三 【算法】:排名第四 IEEE Spectrum 发布了2...

3186
来自专栏二进制文集

《代码整洁之道》

写整洁代码,需要遵循大量的小技巧,贯彻刻苦习得的“整洁感”。这种“代码感”就是关键所在。有些人生而有之。有些人费点劲才能得到。它不仅让我们看到代码的优劣,还予我...

2092
来自专栏C语言C++游戏编程

零基础究竟怎样才可以学好C语言?多年开发老司机告诉你答案!

看到这,你也许有疑问:C语言功能强大,运行这么简单的一个程序就算入门了,没这么简单吧?

1350
来自专栏落影的专栏

程序员进阶之算法练习(二十六)

前言 金三银四,求职黄金月做算法面试题,热热身子。 正文 1.Chess For Three 题目链接 题目大意: 有三个人A,B,C玩剪刀石头布的游戏,但...

4856
来自专栏進无尽的文章

面向对象编程中的六大原则

1. 单一职责原则(Single Responsibility Principle) 2. 里氏替换原则(Liskov Substitution Prin...

1032
来自专栏栗霖积跬步之旅

设计模式的六大原则

单一职责原则: 定义:不要存在多于一个导致类变更的原因。 通俗地说:一个类只负责一项职责。 问题来源:一个类T负责两个职责:职责1和职责2,当因为职责1因需求变...

1900
来自专栏LiveEdu在线科技教育平台

Java 8五大主要功能为开发者提供了哪些便利?

两年前当Java 8发布后,立即受到了业界的欢迎,因为它大大提高了Java的性能。它独特的卖点是,顾及了编程语言的每一个方面,包括JVM(Java虚拟机)和编译...

29713
来自专栏木宛城主

敏捷团队的规范与准则

1.序言 打造一个金诚所至的敏捷团队,需要大家自发的来遵守以及完善相应的规范。大家在自我约束的前提下,彼此之间互相影响,由下而上推动团队的建设。所以规矩、准则...

2679
来自专栏美团技术团队

聊聊clean code

clean code,顾名思义就是整洁的代码,或者说清晰、漂亮的代码,相信大多数工程师都希望自己能写出这样的代码。 也许这是个千人千面的话题,每个工程师都有自己...

4324
来自专栏Fundebug

2018年你需要知道的13个JavaScript工具库

译者按: 你可能已经用到Underscore或者Lodash。本文列举了13个常用的JavaScript工具库来提高开发效率。

1915

扫码关注云+社区

领取腾讯云代金券