《重构HTML:改善Web应用的设计(修订版)》——2.4 正则表达式

简介:

本节书摘来自异步社区《重构HTML:改善Web应用的设计(修订版)》一书中的第2章,第2.4节,作者: 【美】Elliotte Rusty Harold 更多章节内容可以访问云栖社区“异步社区”公众号查看。

2.4 正则表达式

手工检查或者改动一个网站的每一个文件,即使是一个小型网站的少量文件,也是一件十分乏味和费劲的事情。让计算机搜索错误,可以的话同时自动修复错误,这显然是更高效的做法。很多工具都支持这种方式,包括诸如grep、egrep和sed等命令行工具,诸如jEdit、BBEdit、TextPad和PSPad等文本编辑器,当然也包括诸如Java、Perl和PHP等编程语言。所有这些工具都提供了一门专门的搜索语法规则,被称为正则表达式。尽管在不同的工具中它的表现略有不同,但基本语法几乎是一致的。

为达到说明的目的,本节中我将使用jEdit文本编辑器作为搜索和替换工具。选择它的原因在于它提供非常多适合你的特性,GUI也非常合理,而且还是开源的。由于它是用Java编写的,所以本质上说能够运行于任何平台上。

然而,这里我展示的技术当然不会只局限于一个编辑器上。我在工作中常用到的是界面稍为优美的BBEdit,但它只能运行在Mac上。当然还有很多其他的选择,如果你喜欢某一种工具,那就用它吧。其实你需要的是:

  • 完整支持正则表达式的搜索和替换;
  • 递归搜索目录的能力;
  • 过滤搜索文件的能力;
  • 能够显示变更且不需手工去验证的工具;
  • 自动识别不同的字符编码和行尾结束惯例(line-ending conventions)。

满足上述条件的工具应该就够用了。

2.4.1 搜索
正则表达式的第一个目的是查找所有可能是错误的东西。比如,最近我发现在一个文件中,我老是把2006拼错为20066,而且这个错误可能不止一处,所以我需要通过搜索该字符串来检查这个错误。

在jEdit中,你可以使用Directory菜单中的Search/Search执行一个多文件搜索。选中这个菜单项后出现了如图2-6所示的对话框,图中示例有所调整。


599567549d82bd974ea7f27f0619807de9af99e1
  • 需要搜索的字符串(即目标字符串)在第一个输入框中。
  • 用于替换目标字符串的字符串在第二个输入框中。这里我只查找而不替换,所以不用输入替换字符串。
  • Directory单选按钮表示是否搜索多文件。你可以只在当前文件甚至是当前选中的文本中进行搜索。
  • 将Filter设置为.html表示搜索只以.html为后缀的文件。你可以修改此处以搜索不同类型或不同部分的文件。比如,我常常只需搜索那些被命名为news2000.html、news2001.html、news2002.html等旧信息文件。在这种情况下,我需要把Filter设置为news2.html。当然我也可以通过重写过滤器的正则表达式,比如newsdddd.html,搜索到包括news1999.html等更旧的文件。
  • 我还指定了需要搜索文件所在的本地目录,本例中是/Users/elharo/Cafe au Lait/javafaq。
  • 选中Search subdirectories复选框,否则,jEdit不会搜索javafaq的下一层目录,而只是javafaq这一层。
  • 选中Keep dialog复选框,这在搜索完成后还能保持对话框的打开状态。
  • 选中Ignore case复选框,这允许正则表达式忽略字母大小写。对你来说,- 大部分情况下都是要忽略大小写的。
  • 选中Regular expressions复选框,如果你只是查找一个常量字符串,就没有必要选中此项。但是,大部分的搜索都会比单纯的字符串搜索复杂。
  • 选中HyperSearch,这会出现一个显示所有匹配结果的窗口,而不只是下一项的匹配结果。

幸好这个特定的问题看起来已经解决掉了,但我还发现了另一个更严重的问题。由于一些未知因素,我在其中一个网站中的链接中使用了双等号,如下所示:

<a href=="../../index.html">Cafe au Lait</a>

因此,链接无论在哪儿都是失效的。第一步是要找出涉及此问题的所有文件。在这个例子里,错误的字符串是常量,并且在正确的文本中出现的可能性也很小,所以非常容易进行搜索。图2-7的HyperSearch结果显示,这个问题在476个文件中出现了4475次。


c0bc1e0b518888fbbee510b16eb8772654fbc393

在错误不多的情况下,你只用单击每个错误以打开文件,并手工修复就行了。有时这也是必需的,甚至是最简单的解决方案。但是在错误量成千上万时,你就有必要使用工具来修复了。在上面的例子中,解决方法是不言自明的:在Replace with文本框中输入href=,再单击Replace all按钮就行了。

执行此类操作时必须十分小心,否则小错也会酿成大祸。错误的搜索和替换可能是错误问题的根源。在执行整站的操作之前,你应该先在少量的文件上进行搜索和替换,对你的正则表达式测试一番。

更重要的是务必在网站的备份副本上进行操作,在每次更改后务必运行测试套件,并在文件被改动的情况下当场核对,以保证正确性。如果发生了某些错误,编辑器的撤销功能将会非常有用。但并不是所有的编辑器都能有一个足够大的缓冲区(buffer)支持多重撤销,所以处理不了上千次的改动。假如编辑器不支持多重撤销,马上删除正在编辑的副本并用一个原始的副本进行替换,以防止搜索出错。跟其他复杂的代码一样,有时你不得不多花点时间对正则表达式进行排错。

2.4.2 搜索模式
通常你不关心搜索的具体内容,但必须了解它的通用模式。举例来说,要查找刚过去的几年的公元表示法,实际上是要搜索以200开头的四位数字。查找name=value这种形式的属性对时,并不能保证是name=value、name='value'还是name="value"格式。搜索所有不管是否有属性的

起始标签。这些都是使用正则表达式的绝佳场合。

在正则表达式中,特定的字符和模式可以表示其他的字符集合。比如,d表示任意的数字。因此要搜索2000年到2009年中的任意一年,可以使用200d这样的正则表达式,它能匹配2000、2001、2002等一直到2009这些年份。

但是200d这个正则表达式也会匹配12000、200032、12320056或其他可能不是年份的字符串。(准确地说,它匹配符合200d的字符串子串,而不是整个字符串)。因此,你可能希望指明需要匹配前后都有空白③的字符串。元字符s匹配空白,所以现在我们可以将正则表达式重写为s200ds,这样才可以实现只匹配看起来是本世纪头十年中年份的字符串。

当然这还是不能保证匹配到的字符串形式就一定是年份,它也有可能是价格、人数、分数、电影标题等。你需要看一下匹配列表,检查是否是你想要的结果。尤其是在如此简单的情况下,误报的情况需要加以注意。当然,更进一步地完善正则表达式可以避免误报,或者手工删除偶然的匹配,都是可行的。

这里有更多的方法。比如我们在这个搜索中可以使用b200db。元字符b匹配单词的开头或结尾,完全不会选中任何字符。这就可以避免需要选中单词前后的空白,也可以识别在句子末尾的诸如“This is 2008.”中的年份。但是它不能区别是英文句号还是数学中的小数点,所以也会匹配到“in 中的2005。

你可以简单地使用或操作符|来分隔年份,比如:

2000|2001|2002|2003|2004|2005|2006|2007|2008|2009

但单词分界问题还是避免不了。

有时你得暂时停止使用搜索。特别是由CMS、模板页面或者其他程序自动生成的内容时,搜索只能用来找错,定位程序在哪里产生了错误的标记。然后必须改正程序错误才能生成正确的标记。在这种情况下,你就不必太担心误报了,因为所有的更改都是手工执行的。这种搜索只找错不修错。

如果你没有停止使用搜索,并且继续替换,这需要谨慎行事。正则表达式比本书中的例子更棘手,涉及HTML就更不用说有多么狡猾了。不管怎么说,对于清理HTML它都是极有价值的工具。

注解

如果你并没有太多的正则表达式经验,请参考附录A中更多的例子。同时我推荐Jeffrey E. F. Friedl的Mastering Regular Expressions,3rd Edition(O’Reilly,2006)。

相关文章
|
2月前
|
存储 监控 安全
如何在Python Web开发中确保应用的安全性?
如何在Python Web开发中确保应用的安全性?
|
2月前
|
前端开发 JavaScript
探索现代Web应用的微前端架构
【10月更文挑战第40天】在数字时代的浪潮中,Web应用的发展日益复杂多变。微前端架构作为一种新兴的设计理念,正逐步改变着传统的单一前端开发模式。本文将深入探讨微前端的核心概念、实现原理及其在实际项目中的应用,同时通过一个简单的代码示例,揭示如何将一个庞大的前端工程拆分成小而美的模块,进而提升项目的可维护性、可扩展性和开发效率。
|
14天前
|
弹性计算 Java 关系型数据库
Web应用上云经典架构实践教学
Web应用上云经典架构实践教学
Web应用上云经典架构实践教学
|
22天前
|
Kubernetes 安全 Devops
有效抵御网络应用及API威胁,聊聊F5 BIG-IP Next Web应用防火墙
有效抵御网络应用及API威胁,聊聊F5 BIG-IP Next Web应用防火墙
53 10
有效抵御网络应用及API威胁,聊聊F5 BIG-IP Next Web应用防火墙
|
14天前
|
弹性计算 Java 数据库
Web应用上云经典架构实战
本课程详细介绍了Web应用上云的经典架构实战,涵盖前期准备、配置ALB、创建服务器组和监听、验证ECS公网能力、环境配置(JDK、Maven、Node、Git)、下载并运行若依框架、操作第二台ECS以及验证高可用性。通过具体步骤和命令,帮助学员快速掌握云上部署的全流程。
|
2月前
|
前端开发 JavaScript UED
在数字化时代,Web 应用性能优化尤为重要。本文探讨了CSS与HTML在提升Web性能中的关键作用及未来趋势
在数字化时代,Web 应用性能优化尤为重要。本文探讨了CSS与HTML在提升Web性能中的关键作用及未来趋势,包括样式表优化、DOM操作减少、图像优化等技术,并分析了电商网站的具体案例,强调了技术演进对Web性能的深远影响。
40 5
|
2月前
|
机器学习/深度学习 人工智能 JavaScript
JavaScript和TypeScript的未来发展趋势及其在Web开发中的应用前景
本文探讨了JavaScript和TypeScript的未来发展趋势及其在Web开发中的应用前景。JavaScript将注重性能优化、跨平台开发、AI融合及WebAssembly整合;TypeScript则强调与框架整合、强类型检查、前端工程化及WebAssembly的深度结合。两者结合发展,特别是在Vue 3.0中完全采用TypeScript编写,预示着未来的Web开发将更加高效、可靠。
50 4
|
14天前
|
弹性计算 负载均衡 安全
云端问道-Web应用上云经典架构方案教学
本文介绍了企业业务上云的经典架构设计,涵盖用户业务现状及挑战、阿里云业务托管架构设计、方案选型配置及业务初期低门槛使用等内容。通过详细分析现有架构的问题,提出了高可用、安全、可扩展的解决方案,并提供了按量付费的低成本选项,帮助企业在业务初期顺利上云。
|
2月前
|
监控 安全 测试技术
如何在实际项目中应用Python Web开发的安全测试知识?
如何在实际项目中应用Python Web开发的安全测试知识?
34 4
|
2月前
|
机器学习/深度学习 数据采集 Docker
Docker容器化实战:构建并部署一个简单的Web应用
Docker容器化实战:构建并部署一个简单的Web应用