浅谈正则表达式背后的原理

一、写在前面

搞编程的都知道正则表达式是什么东西,这里就不多啰嗦了,需要强调的是,这篇文章并不是教你怎么去使用用正则表达式,正则表达式的语法并不是本文的重点,这篇文章的目的就是剥开正则表达式的语法糖,来看一看正则表达式最本质的原理,如果文章中有错误或者纰漏,欢迎批评指正。

二、什么是语法糖

在上面我提到了语法糖的概念,也许有人还不清楚语法糖是什么东西,这里简单的说一下。

语法糖(Syntactic sugar),也译为糖衣语法,是由英国计算机科学家彼得·约翰·兰达(Peter J. Landin)发明的一个术语,指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。通常来说使用语法糖能够增加程序的可读性,从而减少程序代码出错的机会。——摘自 百度百科

可以这么说吧,像C、C++、Java等等这些编程语言都可以看做成语法糖,因为最终还是得将这些高级程序语言翻译成机器代码,也就是10101……这样的形式,要知道所有的可执行程序最终都可以只需要赋值跳转两种结构即可,而高级语言都是对这两种结构的封装,来适应不同的应用场景,除了机器代码,汇编和这些高级语言都是语法糖,一层一层的包装,达到简化开发的目的,大家想想,如果没有这些语法糖,那我们岂不是得天天用机器代码写程序?

三、算数表达式

这里先引入一个小小的例子,我想在阅读这篇文章的人都知道什么是算数表达式,最基本的算数表达式:

1,2,3,4,5,6,7,8,9,0,……
+,-,*,/,……

这些都是最基本的算数表达式,而由这些最基本的算数表达式可以构造出更加复杂的复合表达式比如1+1,3*5等等,无论是基本的还是复合的,它们都是算数表达式,通过这个例子,来自然的过渡到下面正则表达式的内容,其实本质上算数表达式和正则表达式的道理是差不多的。

四、正则表达式

构成正则表达式最基本的就是给定的字符集∑={c1,c2,c3,……,cn},这就相当于算数表达式中的0,1,3……这些基本算数表达式。
接下来呢,就是他的归纳定义,来告诉我们如何通过最基本的字符集构造出复杂的正则表达式:

  1. 空串ε是正则表达式。
  2. 对于任意字符c∈∑,c是正则表达式
  3. 如果M,N是正则表达式,则以下也是正则表达式:

    选择 M|N = {M,N}
    连接 MN = {mn | m∈M,n∈N}
    闭包 M* = {ε,M,MM,MMM,……}

不难看出,以上的归纳定义给出了正则表达式最基本的的形式,无论多么复杂的正则表达式都是在这个基础上构成的。

现在我们通过一个小例子来加深对上面概念的理解:

给定一个字符集∑={a,b},可以写出那些正则表达式呢?
1.  ε
2.  a,b
3.  ε|ε,ε| a,ε| b ,……
4.  εa,εb,ab,εε,……
5.  a(ε| a),b(ε|b),……
6.  ε*,(a(ε| a))*,……
7.  ……

也就是说,单个的字符都是正则表达式,它们按照上面的定义组合起来依然是正则表达式,正则表达式与正则表达式相互组合又可以生成新的正则表达式,在复杂的正则表达式都是由这些基本的正则表达式构成,当然了上面这些只是该字符集的正则表达式的一小部分,因为这个字符集的正则表达式集合是一个无限集,到这里,我想大家应该有所体会。

我们再来看一个例子:

我们用上面的正则表达式的概念来构造出用来描述C语言标识符的正则表达式:
首先给定字符集,我们都知道C语言的字符集有ASCII码构成。
C语言标识符的格式:以字母或下划线开头,后面跟零个或多个字母、数字或下划线。

该怎么用正则表达式来描述呢?

(a|b|c|……|z|A|B|C|……|Z|_)(a|b|c|……|z|A|B|C|……|Z|0|1|2|3|……|9|_))*

首先来看,这个正则表达式是由两个子表达式连接而成,每个子表达式都是用选择符|构成,又因为第二个子表达式可以出现零或多次,所以加上闭包,是不是看的脑袋都大了,是不是觉得平时什么时候这么写过正则表达式,下面就得说说语法糖的作用啦。

五、正则表达式中的语法糖

大家接触到的正则表达式的语法似乎是有差异的,比如POSIX风格正则表达式和Perl风格正则表达式,要知道无论什么风格的正则表达式它们背后的原理都是一样的,只是在上层提供的语法糖不一样而已,实际应用的过程中都是根据上面的原理演变过来的,语法糖可以大大简化正则表达式的形式,变得更容易阅读和理解,就像下面的对应关系一样。

[c1-cn] == c1|c2|c3|……|cn

e? == ε|e

e+ == (e*)\ε

e{i,j} == i到j个e连接

这里就不一一举例了,无论上面的对应关系中左边的语法如何变化,它所对应的右边的基本原理都是一样的。

六、小结

正则表达式可以写的非常复杂,复杂到除了作者外很少有人看的懂的,曾经我也是一度不能自拔,但随着学习的深入,慢慢的发现,剥开正则表达式表面的东西,去看背后的原理,才有一种恍然大悟的感觉。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


jquery.validate使用攻略(表单校验) 目录 jquery.validate使用攻略1 第一章 jquery.validate使用攻略1 第二章 jQuery.validate.js API7 Custom selectors7 Utilities8 Validato
/\s+/g和/\s/g的区别 正则表达式/\s+/g和/\s/g,目的均是找出目标字符串中的所有空白字符,但两者到底有什么区别呢? 我们先来看下面一个例子: let name = 'ye wen jun';let ans = name.replace(/\s/g, '&#3
自整理几个jquery.Validate验证正则: 1. 只能输入数字和字母 /^[0-9a-zA-Z]*$/g jQuery.validator.addMethod("letters", function (value, element) { return this.optio
this.optional(element)的用法 this.optional(element)是jquery.validator.js表单验证框架中的一个函数,用于表单控件的值不为空时才触发验证。 简单来说,就是当表单控件值为空的时候不会进行表单校验,此函数会返回true,表示校验通过,当表单控件
jQuery.validate 表单动态验证 实际上jQuery.validate提供了动态校验的方法。而动态拼JSON串的方式是不支持动态校验的。牺牲jQuery.validate的性能优化可以实现(jQuery.validate的性能优化见图1.2 jQuery.validate源码 )。 也可
自定义验证之这能输入数字(包括小数 负数 ) <script type="text/javascript"> function onlyNumber(obj){ //得到第一个字符是否为负号 var t = obj.value.charAt(0); //先把非数字的都
// 引入了外部的验证规则 import { validateAccountNumber } from "@/utils/validate"; validator.js /*是否合法IP地址*/ export function validateIP(rule, value,cal
VUE开发--表单验证(六十三) 一、常用验证方式 vue 中表单字段验证的写法和方式有多种,常用的验证方式有3种: data 中验证 表单内容: <!-- 表单 --> <el-form ref="rulesForm" :rules="formRul
正则表达式 座机的: 例子: 座机有效写法: 0316-8418331 (010)-67433539 (010)67433539 010-67433539 (0316)-8418331 (0316)8418331 正则表达式写法 0\d{2,3}-\d{7,8}|\(?0\d{2,3}[)-]?\d
var reg = /^0\.[1-9]{0,2}$/;var linka = 0.1;console.log (reg.test (linka)); 0到1两位小数正则 ^(0\.(0[1-9]|[1-9]{1,2}|[1-9]0)$)|^1$ 不含0、0.0、0.00 // 验证是否是[1-10
input最大长度限制问题 <input type="text" maxlength="5" /> //可以 <input type="number" maxlength="5" /> //没有效
js输入验证是否为空、是否为null、是否都是空格 目录 1.截头去尾 trim 2.截头去尾 会去掉开始和结束的空格,类似于trim 3.会去掉所有的空格,包括开始,结束,中间 1.截头去尾 trim str=str.trim(); // 强烈推荐 最常用、最实用 or $.trim(str);
正则表达式语法大全 字符串.match(正则):返回符合的字符串,若不满足返回null 字符串.search(正则):返回搜索到的位置,若非一个字符,则返回第一个字母的下标,若不匹配则返回-1 字符串.replace(正则,新的字符串):找到符合正则的内容并替换 正则.test(字符串):在字符串中
正整数正则表达式正数的正则表达式(包括0,小数保留两位): ^((0{1}.\d{1,2})|([1-9]\d.{1}\d{1,2})|([1-9]+\d)|0)$正数的正则表达式(不包括0,小数保留两位): ^((0{1}.\d{1,2})|([1-9]\d.{1}\d{1,2})|([1-9]+
JS 正则验证 test() /*用途:检查输入手机号码是否正确输入:s:字符串返回:如果通过验证返回true,否则返回false /function checkMobile(s){var regu =/[1][3][0-9]{9}$/;var re = new RegExp(regu);if (r
请输入保留两位小数的销售价的正则: /(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/ 1.只能输入英文 <input type="text" onkeyup="value
判断价格的正则表达式 价格的正则表达式 /(^[1-9]\d*(\.\d{1,2})?$)|(^0(\.\d{1,2})?$)/; 1 解析:价格符合两种格式 ^ [1-9]\d*(.\d{1,2})?$ : 1-9 开头,后跟是 0-9,可以跟小数点,但小数点后要带上 1-2 位小数,类似 2,2
文章浏览阅读106次。这篇文章主要介绍了最实用的正则表达式整理,比如校验邮箱的正则,号码相关,数字相关等等,本文给大家列举的比较多,需要的朋友可以参考下。_/^(?:[1-9]d*)$/ 手机号
文章浏览阅读1.2k次。4、匹配中的==、an==、== an9、i9 == "9i"和99p==请注意下面这部分的作用,它在匹配中间内容的时候排除了说明:当html字符串如下时,可以匹配到两处,表示匹配的字符串不包含and且不包含空白字符。说明:在上面的正则表达式中,_gvim正则表达式匹配不包含某个字符串
文章浏览阅读897次。【代码】正则表达式匹配a标签的href。_auto.js 正则匹配herf