(转)为什么需要正则表达式 by 王珢

2023-05-16

为什么需要正则表达式

by 王垠

学习Unix最开头,大家都学过正则表达式(regexp)。可是有没有人考虑过我们为什么需要正则表达式?

正则表达式本来的初衷是用来从无结构的字符串中提取信息,殊不知这正好是Unix的缺陷所在。Unix用无结构的字符串来表示数据,导致了诸多复杂的基于regexp的软件的诞生。sed, AWK, Perl, … 都是为了同样的目的来到这个世界上的。如果不是因为Unix用字符串来表示数据,我们就会拥有按数据结构类型的直接存储,而不需要折腾regexp。正则表达式有它自己的价值(针对自然语言),但是我们其实不需要把它应用到程序语言和操作系统里面。

正则表达式本身用一个字符串来表示,这带来另外一些问题。因为正则表达式的本质不是字符串,而是一个数据结构。学过计算理论的人可能知道这个数据结构叫做NFA(nondeterministic finite automaton,非确定性有限自动机)。所有的数据结构应该由程序语言本身来表示,就像用Java构造一个对象用 new ClassA("a") 一样。但是正则表达式强迫你把这个简单的构造函数调用写成一个字符串。所以在这个比方之下,你得写成new ClassA(\"a\")。这样当你想要组合这些表达式的时候就发现,正则表达式几乎都是不可组合(compose)的。你几乎不可能不能把两个regexp的变量A和B安全拼接成一个,比如用Java的字符串拼接A+B。因为你不知道这两个字符串拼在一起之后,那些稀奇古怪的符号会出现什么交叉反应,使得最后的识别的东西根本不是你想要的。

在正则表达式中,由于正则表达式本身的构造函数与数据本身合并到一起,我们不得不对某些“特殊字符”进行escape。这些特殊字符,其实是用来描述NFA的记号,它们属于更高一层的语言。可是在正则表达式里,它们与NFA节点里的字符混为一谈。比如很简单的一个block comment的正则表达式,却要写成这个样子:


/\\*([^\\*]|[^/])*\\*/
  

显然这样的表达式很容易出错。 如果我们用程序语言的表达式来构造这个表达式,它应该是这样:


(@... "/*" (@*(@!"*/")) "*/" )
  

在这个我自己设计的Scheme表达式里,以@开头的标识符都是构造函数。其中@...是构造sequence,@* 是构造一个zero-or-more的匹配,@!构造一个否定匹配。这个表达式是说:“以/ *开头,接着零个或者多个不是* /的字符,最后接着一个* /。这样一来清晰明了,什么表达式在什么“层次”都很清楚,不需要什么反斜杠escape,而且这样的表达式可以compose。比如:


(define reg1 (@... "/*" (@*(@!"*/")) "*/" ))
(define reg2 (@+ "foo"))
(define reg3 (@= "b"))
  

定义这三个表达式之后,我们之后可以用像(@... reg1 (@or reg2 reg3)) 这样的表达式来连接3个不同的表达式,构造出更大的表达式。这样的构造可以无限的扩展。从这里以及以往的经验,我总结出一个普遍适用的程序设计的教训:尽量不要把多个层次的语言“压缩”到一层。我们也看到正则表达式与“Unix哲学”有很大关系。我没有考古,所以不知道孰先孰后,但是它们肯定有直接的因果关系。两者都是Unix复杂性的来源。


This article was posted at yinwang’s sina blog,
on 2012-05-17.
Though it’s not available now.

转载于:https://www.cnblogs.com/zhanglong8681/p/4814118.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

(转)为什么需要正则表达式 by 王珢 的相关文章

  • istanbul —— JavaScript 代码覆盖率检查工具

    istanbul 是一个 JavaScript 的代码覆盖率检查工具 https yqfile alicdn com e6425e746f3af8cef9c3e64dde6ff2f9a336929d png 34 gt 文章转载自 开源中国
  • vscode怎么修改颜色主题里的某种颜色

    我习惯用深色主题 齿轮 gt 颜色主题 gt monokai是我的菜 比较精神 又不刺眼 但是这个主题的注释的颜色太浅了 几乎和背景重合 注释很重要 能体现和记录自己的代码思路 所有 改变一下comment的颜色很重要 在vscode图标右
  • 双系统linux安装分区详解,win10环境下安装Ubantu双系统(详解图解)

    1 准备工作 xff1a 先去ubantu官网 https www ubuntu com download 去下载ubantu镜像 根据自己的实际情况选择32位的或者64位的 xff0c 现在的电脑大部分已经都是4g内存了 xff0c 我推
  • Ubuntu - 硬盘分区、格式化、自动挂载配置

    Ubuntu系统的硬盘空间不够用了 xff0c 需要增加新的硬盘扩容 将硬盘分区 格式化 自动挂载配置的整个过程记下来 xff0c 备忘 运行环境 Enviroment Ubuntu 10 10 一 硬盘分区 Hard disk add n
  • linux下安装F-prot杀毒软件

    一 f xff0d prot的安装 1 首先我们要创建一个带有超级权限的用户 sudo passwa root 2 su 切换用户 3 下载F prot http www f prot com download home user down
  • 使用Github自动构建Docker

    原文链接 xff1a http yangbingdong com 2017 docker automated build by github 一开始玩Docker总是用别人的镜像确实很爽歪歪 But xff0c 如果要定制个性化的Image
  • 常用 API 函数(6): 菜单函数

    AppendMenu在指定的菜单里添加一个菜单项CheckMenuItem复选或撤消复选指定的菜单条目CheckMenuRadioItem指定一个菜单条目被复选成 34 单选 34 项目CreateMenu创建新菜单CreatePopupM
  • 视觉slam闭环检测之-DBoW2 -视觉词袋构建

    视觉slam闭环检测之 DBoW2 视觉词袋构建 利用 BoVW 表示图像 xff0c 将图像进行结构化描述 BoVW思想是将图像特征整合成视觉单词 xff0c 将图像特征空间转化成离散的视觉字典 将新的图像特征映射到视觉字典中最近邻视觉字
  • Boosting算法简介

    一 Boosting算法的发展历史 Boosting算法是一种把若干个分类器整合为一个分类器的方法 xff0c 在boosting算法产生之前 xff0c 还出现过两种比较重要的将多个分类器整合为一个分类器的方法 xff0c 即boostr
  • 关于嵌入式的学习和职业发展

    最近我的工作太忙了 身边朋友问我如何学习嵌入式 xff0c 在这个行业健康的发展 我一直未能做一个系统的回答 这里我想写篇文章 xff0c 彻底的回答这个问题 嵌入式 xff0c 这是个术语 在我看来 xff0c 嵌入式系统是 xff1a
  • Docker Hub + Github 自动化构建docker镜像

    自动创建 xff08 Automated Builds xff09 功能对于需要经常升级镜像内程序来说 xff0c 十分方便 有时候 xff0c 用户创建了镜像 xff0c 安装了某个软件 xff0c 如果软件发布新版本则需要手动更新镜像
  • ubuntu下旋转屏幕

    2019独角兽企业重金招聘Python工程师标准 gt gt gt ubuntu下把屏幕竖起来的方法很简单 xff1a xrandr o left 向左旋转90度 xrandr o right 向右旋转90度 xrandr o invert
  • Java 如何实现线程间通信

    正常情况下 xff0c 每个子线程完成各自的任务就可以结束了 不过有的时候 xff0c 我们希望多个线程协同工作来完成某个任务 xff0c 这时就涉及到了线程间通信了 本文涉及到的知识点 xff1a thread join object w
  • rtmp拉流测试工具

    http www cutv com demo live test swf 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
  • 微信PC客户端无法发送图片,怎么解决?

    今天登陆电脑的微信客户端 xff0c 无法发送截图图片 xff0c 该怎么办 xff1f 解决方法 1 在任务栏找到程序 xff0c 右键找到设置 2 找到通用设置下的清除聊天记录 3 重启Pc微信客户端就可以 PS 本人测试过 xff0c
  • sql server 索引总结一

    一 存储结构 在SQL Server中 xff0c 有许多不同的可用排列规则选项 二进制 xff1a 按字符的数字表示形式排序 ASCII码中 xff0c 用数字32表示空格 xff0c 用68表示字母 34 D 34 因为所有内容都表示为
  • CSS 为什么这么难学?

    最近半年 xff0c 我一直都没在知乎上遇到好的前端问题 xff0c 而这个问题 xff0c 问到我心坎上了 在过去一年的教学过程中 xff0c 不断有学生尝试理性地理解 CSS xff0c 都以失败告终 我告诉他们 CSS 是没有逻辑可言
  • 时间复杂度分析经典问题——最大子序列和

    时间复杂度经典问题 最大子列和问题 最大子序列和问题 最大子列和问题是非常经典的问题 xff0c 基本上讲算法的书都会将这个例子 xff0c 用此例题来讲解算法时间复杂度的重要性 xff0c 对比不同算法的时间复杂度 最大子列和问题如下 x
  • 无法运行宏,可能是因为该宏在此工作簿中不可用,或者所有的宏都被禁用的解决方法...

    此行为发生以下条件之一都为真时 xff1a 宏存储在未打开的文件中 宏已被禁用 若要确定是否已禁用了宏 xff0c 请按照下列步骤操作 xff1a 单击 Microsoft Office 按钮 xff0c 然后单击 Excel 选项 单击

随机推荐

  • h3c vlan配置

    1 基于端口的VLAN配置命令 SWA vlan 10 创建VLAN SWA vlan10 port Ethernet1 0 1 向当前VLAN添加端口 SWA vlan 20 创建VLAN SWA vlan20 port Ethernet
  • LMDB概述

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 发现一篇讲解LMDB不错的文章 xff0c 记录一下 xff0c 原文在这里 Overview homepage http symas com mdb https gith
  • GPU加速的FAST特征提取 Faster than FAST: GPU-Accelerated Frontend for High-Speed VIO (IROS 2020)

    在许多的VIO Pipeline中 xff0c 视觉特征通常依靠图像数据的detection和tracking 这两个部分通常会比较耗时 xff0c 比如一些经典的算子 xff0c 运算量都比较大 xff0c 如果将这些视觉前端用GPU进行
  • 什么是死锁及死锁的必要条件和解决方法【转】

    来自 xff1a http blog 163 com yanenshun 64 126 blog static 128388169200982444858590 fromdm amp fromSearch amp isFromSearchE
  • 获取C# RadioButton选中值

    C RadioButton的一些属性介绍 1 C RadioButton只允许用户从几个选项中选择一个 xff0c 同一个容器中一次只能选择一个按钮 xff1b 2 C RadioButton的Appearance属性 xff1a 根据的以
  • vc-api-枚举所有子窗口实例

    我经常想枚举一个父窗口的所有子窗口 xff0c 网上搜索了很多都没有搞的太懂 xff0c 经过多次实践 xff0c 总算搞明白了 xff0c 发一个最简单的实例 xff0c 希望能给大家带来帮助 实例 xff1a 枚举QQ登陆这个窗口所有的
  • VC 获取鼠标下面的窗口

    POINT pt GetCursorPos amp pt 得到鼠标下面的窗口句柄 HWND hWnd 61 WindowFromPoint pt 得到鼠标所在的子窗口句柄 HWND hChild 61 ChildWindowFromPoin
  • [SE]软件项目需求分析为什么困难

    有几种原因使需求分析变得困难 xff1a xff08 1 xff09 客户说不清楚需求 xff1b xff08 2 xff09 需求自身经常变动 xff1b xff08 3 xff09 分析人员或客户理解有误 1 客户说不清楚需求 有些客户
  • C++到底还能做什么?

    嗯 xff0c 这是一位朋友发到我邮箱里面的 xff0c 很奇怪 xff0c 发到了gmail邮箱 xff0c 而不是我常用的hotmail邮箱哈 我呢 xff0c 试着回答一下 xff0c 如果回答得不好 xff0c 叫做肖某人学艺不精
  • Docker 创建 MySQL 容器

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 1 拉取镜像 docker pull mysql 5 7 2 查看当前所有的镜像 docker image ls 3 创建并启动一个容器 docker run name t
  • 深入理解Arrays.sort()

    翻译人员 铁锚 翻译日期 2013年11月16日 原文链接 Deep Understanding of Arrays sort T Comparator lt super T gt c Arrays sort T Comparator lt
  • 18个实时音视频开发中会用到开源项目

    实时音视频的开发学习有很多可以参考的开源项目 一个实时音视频应用共包括几个环节 xff1a 采集 编码 前后处理 传输 解码 缓冲 渲染等很多环节 每一个细分环节 xff0c 还有更细分的技术模块 比如 xff0c 前后处理环节有美颜 滤镜
  • px4 uavcan linux,UAVCAN - UAVCAN Bootloader - 《PX4中文维基》 - 书栈网 · BookStack

    安装UAVCAN启动程序警告 xff1a 无人机控制器局域网络 Unmanned Aerial Vehicle Controller Area Network xff0c UAVCAN 设备通常在出厂时就预安装了启动程序 如果你不对UAVC
  • VISTA -MIT开源基于数据驱动的自动驾驶仿真引擎

    引言 VISTA 是MIT开源的一个基于数据驱动的用于自动驾驶感知和控制的仿真引擎 VISTA API提供了一个接口 xff0c 用于将真实世界的数据集转换为具有dynamic agents sensor suites task objec
  • 计算机管理储存u盘无法使用,解决电脑识别不出U盘的问题

    电脑识别不出U盘怎么样 要解决这个问题 xff0c 首先我们要确定的是U盘在其他电脑上使用正常 xff0c 而且你的电脑USB接口也是一切正常的 xff0c 插入电脑后虽然有反应 xff0c 但就无法正确显示出盘符 xff0c 资源管理器也
  • 介绍:成为一名 Jenkins 贡献者的旅程

    转自Jenkins 中文社区 作为一名软件工程师 xff0c 这些年来在我工作过的不同公司里用到过许多开源软件 xff08 包括框架 库 工具等 xff09 然而 xff0c 在此之前我从没有以一名贡献者的身份参与过开源项目 自从我向 Je
  • 国内嵌入式公司比较排名

    随着 ARM内核的应用越来越广泛 xff0c 从手机到电视机 xff0c 从大型工控设备到小型的家电应用 xff0c 都能找到 ARM内核的嵌入式产品 而由此引领了一番全球嵌入式领域火热的变化 xff0c 当然 xff0c 国内的嵌入式领域
  • MYSQL常用操作及python操作MYSQL常用类

    Mysql 常见操作 数据库操作 创建数据库 create database fuzjtest 删除数据库 drop database fuzjtest 查询数据库 show databases 切换数据库 use databas 1231
  • Windows Server 2008的认证监视工具

    管理证书的一个主要目标是获得企业安全的一种高级水平 应当认真对待身份和访问管理问题 在本文中 xff0c 笔者将简要地讨论认证授权 xff0c 然后探讨使用特定的证书监视工具 xff08 如PKIView msc和certutil exe
  • (转)为什么需要正则表达式 by 王珢

    为什么需要正则表达式 by 王垠 学习Unix最开头 xff0c 大家都学过正则表达式 regexp 可是有没有人考虑过我们为什么需要正则表达式 xff1f 正则表达式本来的初衷是用来从无结构的字符串中提取信息 xff0c 殊不知这正好是U