《重构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)。

相关文章
|
9月前
|
前端开发 算法 API
构建高性能图像处理Web应用:Next.js与TailwindCSS实践
本文分享了构建在线图像黑白转换工具的技术实践,涵盖技术栈选择、架构设计与性能优化。项目采用Next.js提供优秀的SSR性能和SEO支持,TailwindCSS加速UI开发,WebAssembly实现高性能图像处理算法。通过渐进式处理、WebWorker隔离及内存管理等策略,解决大图像处理性能瓶颈,并确保跨浏览器兼容性和移动设备优化。实际应用案例展示了其即时处理、高质量输出和客户端隐私保护等特点。未来计划引入WebGPU加速、AI增强等功能,进一步提升用户体验。此技术栈为Web图像处理应用提供了高效可行的解决方案。
|
8月前
|
缓存 前端开发 应用服务中间件
Web端实时通信技术SSE在携程机票业务中的实践应用
本文介绍了携程机票前端基于Server-Sent Events(SSE)实现服务端推送的企业级全链路通用技术解决方案。文章深入探讨了 SSE 技术在应用过程中包括方案对比、技术选型、链路层优化以及实际效果等多维度的技术细节,为类似使用场景提供普适性参考和借鉴。该方案设计目标是实现通用性,适用于各种网络架构和业务场景。
256 1
|
9月前
|
缓存 前端开发 应用服务中间件
Web端实时通信技术SSE在携程机票业务中的实践应用
本文介绍了携程机票前端基于Server-Sent Events(SSE)实现服务端推送的企业级全链路通用技术解决方案。文章深入探讨了 SSE 技术在应用过程中包括方案对比、技术选型、链路层优化以及实际效果等多维度的技术细节,为类似使用场景提供普适性参考和借鉴。
349 7
|
12月前
|
中间件 关系型数据库 数据库
docker快速部署OS web中间件 数据库 编程应用
通过Docker,可以轻松地部署操作系统、Web中间件、数据库和编程应用。本文详细介绍了使用Docker部署这些组件的基本步骤和命令,展示了如何通过Docker Compose编排多容器应用。希望本文能帮助开发者更高效地使用Docker进行应用部署和管理。
364 19
|
Web App开发 编解码 vr&ar
使用Web浏览器访问UE应用的最佳实践
在3D/XR应用开发中,尤其是基于UE(虚幻引擎)开发的高精度场景,传统终端因硬件局限难以流畅运行高帧率、复杂效果的三维应用。实时云渲染技术,将渲染任务转移至云端服务器,降低终端硬件要求,确保用户获得流畅体验。具备弹性扩展、优化传输协议、跨平台支持和安全性等优势,适用于多种终端和场景,特别集成像素流送技术,帮助UE开发者实现低代码上云操作,简化部署流程,保留UE引擎的强大开发能力,确保画面精美且终端轻量化。
573 17
使用Web浏览器访问UE应用的最佳实践
|
Kubernetes 安全 Devops
有效抵御网络应用及API威胁,聊聊F5 BIG-IP Next Web应用防火墙
有效抵御网络应用及API威胁,聊聊F5 BIG-IP Next Web应用防火墙
316 10
有效抵御网络应用及API威胁,聊聊F5 BIG-IP Next Web应用防火墙
|
弹性计算 Java 关系型数据库
Web应用上云经典架构实践教学
Web应用上云经典架构实践教学
311 2
Web应用上云经典架构实践教学
|
弹性计算 Java 数据库
Web应用上云经典架构实战
本课程详细介绍了Web应用上云的经典架构实战,涵盖前期准备、配置ALB、创建服务器组和监听、验证ECS公网能力、环境配置(JDK、Maven、Node、Git)、下载并运行若依框架、操作第二台ECS以及验证高可用性。通过具体步骤和命令,帮助学员快速掌握云上部署的全流程。
354 1
|
前端开发 JavaScript UED
在数字化时代,Web 应用性能优化尤为重要。本文探讨了CSS与HTML在提升Web性能中的关键作用及未来趋势
在数字化时代,Web 应用性能优化尤为重要。本文探讨了CSS与HTML在提升Web性能中的关键作用及未来趋势,包括样式表优化、DOM操作减少、图像优化等技术,并分析了电商网站的具体案例,强调了技术演进对Web性能的深远影响。
217 5
|
弹性计算 负载均衡 安全
云端问道-Web应用上云经典架构方案教学
本文介绍了企业业务上云的经典架构设计,涵盖用户业务现状及挑战、阿里云业务托管架构设计、方案选型配置及业务初期低门槛使用等内容。通过详细分析现有架构的问题,提出了高可用、安全、可扩展的解决方案,并提供了按量付费的低成本选项,帮助企业在业务初期顺利上云。
370 0