前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >程序员眼中的正则表达式

程序员眼中的正则表达式

作者头像
用户1608022
发布2018-04-11 13:18:08
8850
发布2018-04-11 13:18:08
举报

写程序时,很多时候就是在跟字符串打交道,用户输入的内容是字符串, 响应用户的输出也是字符串。 假如程序是基于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[^\.]*$))),也许这不能算标准或完美的解决方案,但胜在快捷,把去网上找其他的配置方案的时间和再做进一步配置的功夫节省了下来。

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

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

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

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

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

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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2016-09-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 带你撸出一手好代码 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档