深入浅出之正则表达式

合集下载

验证账号是否合法的正则表达式

验证账号是否合法的正则表达式

验证账号是否合法的正则表达式标题:深度解析:如何使用正则表达式验证账号是否合法在当今数字化的世界里,账号验证已成为至关重要的一环。

无论是在网站注册、登录还是进行身份验证,验证账号的合法性是必不可少的环节。

而在程序开发中,使用正则表达式来验证账号是否合法更是一种常见的做法。

那么,正则表达式到底是什么?它又是如何验证账号是否合法的呢?本文将从深入浅出的角度为您逐步解析。

1. 什么是正则表达式?我们先来了解什么是正则表达式。

正则表达式,又称正规表示式、常规表示法、规则运算式,是计算机科学的一个概念。

它是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及与之的逻辑关系,组成一个规则表达式,用来表达对字符串的一种过滤逻辑。

简单来说,正则表达式是一种通用的字符串匹配表达式。

2. 正则表达式验证账号是否合法的原理接下来,我们来了解正则表达式是如何验证账号是否合法的。

在验证账号合法性时,常见的验证要求包括:长度限制、字符类型、特殊字符限制等。

正则表达式通过使用特定的符号和字符来表示字符串匹配的规则,从而能够高效地验证账号是否符合预定的规范。

3. 使用正则表达式验证账号是否合法的实例举个例子来说明:假设我们要验证一个账号是否符合以下规范:长度为6-12位,仅包含字母和数字。

那么对应的正则表达式可以写成:^[a-zA-Z0-9]{6,12}$。

其中,^表示匹配字符串开头,$表示匹配字符串结尾,[a-zA-Z0-9]表示包含字母和数字的字符集合,{6,12}表示字符长度为6-12位。

通过这个简单的例子,我们可以看到正则表达式是如何应用于验证账号合法性的。

4. 账号合法性验证的实际场景应用在实际的程序开发中,验证账号合法性是非常常见的需求。

不论是在用户注册时,对密码进行复杂度验证,还是在唯一识别信息号、通信方式号等信息的验证,都可以使用正则表达式来实现。

而正则表达式的灵活性和强大性,使得它成为了验证账号合法性不可或缺的工具。

regexp正则表达式

regexp正则表达式

regexp正则表达式(原创版)目录1.正则表达式的概念和作用2.正则表达式的基本语法3.正则表达式的应用场景4.正则表达式的优缺点正文正则表达式(Regular Expression,简称 regexp)是一种用于处理字符串的强大工具,它可以用来检查字符串是否符合某种模式、提取字符串中的特定信息等。

正则表达式广泛应用于计算机科学和编程领域,例如文本编辑器、搜索引擎、数据验证等。

正则表达式的基本语法包括以下几种元素:1.字面字符:例如 abc、123 等,它们直接表示字符本身。

2.元字符:例如.(匹配任意字符)、*(匹配零个或多个前面的字符)、+(匹配一个或多个前面的字符)等,它们用来表示字符的匹配方式。

3.字符类:例如 [a-zA-Z](匹配所有英文字母)、[0-9](匹配所有数字)等,用来匹配特定类别的字符。

4.边界匹配符:例如^(表示字符串的开头)、$(表示字符串的结尾)等,用来指定匹配的位置。

5.分组和捕获:使用圆括号表示一个分组,可以对分组进行命名捕获,以满足特定需求。

正则表达式的应用场景包括但不限于:1.数据验证:检查用户输入的数据是否符合某种格式要求,例如邮箱地址、手机号码等。

2.文本处理:对文本进行搜索、替换、分割等操作,例如在网页中提取所有链接、去除文本中的空格等。

3.数据分析:对大量数据进行筛选、统计等操作,例如分析日志文件、提取表格数据等。

正则表达式的优点主要体现在其简洁、灵活和强大的表达能力上,它可以用来处理各种复杂的字符串问题。

然而,正则表达式也存在一定的缺点,例如语法较为复杂、不易理解和维护等。

对于初学者来说,需要花费一定时间和精力来学习和掌握正则表达式。

总之,正则表达式是一种重要的计算机技术,它在各个领域都发挥着重要作用。

python正则表达式_深入浅出

python正则表达式_深入浅出
python 的正则表达式 re
延伸阅读:python 的 内建函数 和 subprocess 。此文是本系列的第三篇文章了,和 之前一样,内容出自官方文档,但是会有自己的理解,并非单纯的翻译。所以,如果我理解 有误,欢迎指正,谢谢。
本模块提供了和 Perl 里的正则表达式类似的功能,不关是正则表达式本身还是被搜索 的字符串,都可以是 Unicode 字符,这点不用担心,python 会处理地和 Ascii 字符一样漂 亮。
>>> re.match('<(?P<tagname>\w*)>.*</(?P=tagname)>', '<h1>xxx</h1>') # 这个匹配
<_sre.SRE_Match object at 0xb69588e0>
(?#...)
注释,圆括号里的内容会被忽略。
(?=...)
如果 ... 匹配接下来的字符,才算匹配,但是并不会消耗任何被匹配的字符。例如 Isaac (?=Asimov) 只会匹配后面跟着 'Asimov' 的 'Isaac ',这个叫做“前瞻断言”。 需要后缀匹配
正则表达式使用反斜杆(\)来转义特殊字符,使其可以匹配字符本身,而不是指定其 他特殊的含义。这可能会和 python 字面意义上的字符串转义相冲突,这也许有些令人费 解。比如,要匹配一个反斜杆本身,你也许要用'\\\\'来做为正则表达式的字符串,因为正 则表达式要是\\,而字符串里,每个反斜杆都要写成\\。
如有由 id 或者 name 指定的组存在的话,将会匹配 yes-pattern,否则将会匹配 nopattern,通常情况下 no-pattern 也可以省略。例如:()可以匹配 '<user@>' 和 'user@',但是不会匹配 '<user@'。

正则表达式语法大全

正则表达式语法大全

正则表达式语法大全前言:一般开发中都会接触到正则表达式,作为一名合格的前端,也应该了解一下正则表达式编写原则,便于自己也能快速编写想要的正则表达式。

1、作用(正则表达式是一种字符串匹配的模式)数据验证:比如电话号码、邮箱等替换文本:快速找到特定文本,用于替换快速提取字符串:基于匹配原则,快速从文档中查找或提取子字符串2、语法(普通字符+特殊字符)普通字符[abc] 匹配[...]的所有字符[^abc] 取反,除了[...]的其他字符[A-Z] 区间字母A到Z.匹配除(\n换行符 \r 回车符)的任何单个字符\s \S 匹配所有,\s所有空白符,包括换行 \S非空白符,不包括换行\w 匹配字母、数字、下划线特殊字符$ 结尾位置(匹配$字符----\$)^ 开始位置(匹配$字符----\^)() 子表达式开始和结束(匹配字符----\( 和 \))* 匹配零次或多次(匹配字符----\*)+匹配一次或多次(匹配字符----\+)匹配零次或一次(匹配字符----\?)| 两项间的一个(匹配字符----\|)限定符{n} n为非负整数,匹配n次{n,} n为非负整数,至少n次{n,m} n为非负整数,n<=m,最少n次,最多m次修饰符i 不区分大小写g 全局匹配m 多行匹配s 特殊字符远点包含换行符3、常用场景•16进制颜色/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/以#开始,6或3个字符(A-F、a-f、0-9)结尾•电话号码/^1(3\d|4[5-9]|5[0-35-9]|6[2567]|7[0-8]|8\d|9[0-35-9])\d{8}$/以1开头,3可跟任一数字(\d),4可跟5-9,5可跟0-3或5-9 ,6后2567其中一个,7后是0-8,8后任一数字,9后是0-3或3-5,其余8位是任意数字(\d{8})•身份证号/^[1-9]\d{5}(19|20|21)\d{2}(0[1-9]|10|11|12)(0[1-9]|[1-2]\d|30|31)\d{3}[\dX]$/ 第一位在0-9区间,后面是5位任意数字,4位年份(19、20、21开头,后两位任意),两位代表月份(0开头的1-9或者是10、11、12),两位日期(01-31),三位顺序码,最后一位是校验码,可数字可X•网址/^((https?):)?\/\/([^?:/]+)(:(\d+))?(\/[^?]*)?(\?(.*))?/•邮箱^[A-Za-z0-9-_\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$ 名称有汉字([\ue00-\u9fa5])、字母([a-zA-z])、数字、下划线、中划线,域名有数字、字母、下划线、中划线4、使用方法字符串.match(正则):返回符合的字符串,若不满足返回null字符串.search(正则):返回搜索到的位置,若非一个字符,则返回第一个字母的下标,若不匹配则返回-1字符串.replace(正则,新的字符串):找到符合正则的内容并替换正则.test(字符串):在字符串中查找符合正则的内容,满足则返回true,反之为false说明:new RegExp(规则).test(字符串)和上面写法作用相同。

正则表达式书

正则表达式书

正则表达式书
如果您想学习正则表达式,以下是一些推荐的正则表达式书籍:
1. 《精通正则表达式》(作者:弗瑞德):这本书是正则表达式领域的经典之作,深入浅出地介绍了正则表达式的概念、语法和用法,并提供了大量的示例和练习题,是学习正则表达式的必备书籍。

2. 《正则表达式必知必会》(作者:立山):这本书是一本比较薄的正则表达式入门书籍,适合初学者使用。

它介绍了正则表达式的基本概念和语法,并通过实例演示了如何使用正则表达式进行文本处理和模式匹配。

3. 《Regex Recipes for Java》(作者:麦卡费尔特):这本书是一本专门针对Java的正则表达式教程,介绍了Java中正则表达式的用法和技巧。

它通过丰富的示例和练习题,帮助读者深入了解正则表达式的应用。

这些书籍都是学习正则表达式的经典之作,其中包含了丰富的示例和练习题,可以帮助您深入了解正则表达式的概念、语法和用法,提高您的编程技能。

正则表达式-语法大全

正则表达式-语法大全

正则表达式-语法⼤全1. 正则表达式规则1.1 普通字符字母、数字、汉字、下划线、以及后边章节中没有特殊定义的标点符号,都是"普通字符"。

表达式中的普通字符,在匹配⼀个字符串的时候,匹配与之相同的⼀个字符。

,匹配结果是:成功;匹配到的内容是:"c";匹配到的位置是:开始于2,结束于3。

(注:下标从0开始还是从1开始,因当前编程语⾔的不同⽽可能不同),匹配结果是:成功;匹配到的内容是:"bcd";匹配到的位置是:开始于1,结束于4。

1.2 简单的转义字符⼀些不便书写的字符,采⽤在前⾯加 "/" 的⽅法。

这些字符其实我们都已经熟知了。

表达式可匹配/r, /n代表回车和换⾏符/t制表符//代表 "/" 本⾝还有其他⼀些在后边章节中有特殊⽤处的标点符号,在前⾯加 "/" 后,就代表该符号本⾝。

⽐如:^, $ 都有特殊意义,如果要想匹配字符串中 "^" 和 "$" 字符,则表达式就需要写成 "/^" 和 "/$"。

表达式可匹配/^匹配 ^ 符号本⾝/$匹配 $ 符号本⾝/.匹配⼩数点(.)本⾝这些转义字符的匹配⽅法与 "普通字符" 是类似的。

也是匹配与之相同的⼀个字符。

,匹配结果是:成功;匹配到的内容是:"$d";匹配到的位置是:开始于3,结束于5。

1.3 能够与 '多种字符' 匹配的表达式正则表达式中的⼀些表⽰⽅法,可以匹配 '多种字符' 其中的任意⼀个字符。

⽐如,表达式 "/d" 可以匹配任意⼀个数字。

虽然可以匹配其中任意字符,但是只能是⼀个,不是多个。

这就好⽐玩扑克牌时候,⼤⼩王可以代替任意⼀张牌,但是只能代替⼀张牌。

正则表达式(正则表达式括号的作用)

正则表达式(正则表达式括号的作⽤)正则表达式之前学习的时候,因为很久没怎么⽤,或者⽤的时候直接找⽹上现成的,所以都基本忘的差不多了。

所以这篇⽂章即是笔记,也让⾃⼰再重新学习⼀遍正则表达式。

其实平时在操作⼀些字符串的时候,⽤正则的机会还是挺多的,之前没怎么重视正则,这是⼀个错误。

写完这篇⽂章后,发觉⼯作中很多地⽅都可以⽤到正则,⽽且⽤起来其实还是挺爽的。

正则表达式作⽤ 正则表达式,⼜称规则表达式,它可以通过⼀些设定的规则来匹配⼀些字符串,是⼀个强⼤的字符串匹配⼯具。

正则表达式⽅法基本语法,正则声明js中,正则的声明有两种⽅式1. 直接量语法:1var reg = /d+/g/2. 创建RegExp对象的语法1var reg = new RegExp("\\d+", "g");这两种声明⽅式其实还是有区别的,平时的话我⽐较喜欢第⼀种,⽅便⼀点,如果需要给正则表达式传递参数的话,那么只能⽤第⼆种创建RegExp的形式格式:var pattern = new RegExp('regexp','modifier');regexp:匹配的模式,也就是上⽂指的正则规则。

modifier: 正则实例的修饰符,可选值有:i : 表⽰区分⼤⼩写字母匹配。

m :表⽰多⾏匹配。

g : 表⽰全局匹配。

传参的形式如下:我们⽤构造函数来⽣成正则表达式1var re = new RegExp("^\\d+$","gim");这⾥需要注意,反斜杠需要转义,所以,直接声明量中的语法为\d,这⾥需要为\\d那么,给它加变量,就和我们前⾯写的给字符串加变量⼀样了。

1 2var v = "bl";var re =new RegExp("^\\d+" + v + "$","gim"); // re为/^\d+bl$/gim⽀持正则的STRING对象⽅法1. search ⽅法作⽤:该⽅法⽤于检索字符串中指定的⼦字符串,或检索与正则表达式相匹配的字符串基本语法:stringObject.search(regexp);返回值:该字符串中第⼀个与regexp对象相匹配的⼦串的起始位置。

python正则表达式详解

python正则表达式详解Python正则表达式详解正则表达式是一种强大的文本处理工具,它可以用来匹配、查找、替换文本中的特定模式。

在Python中,正则表达式是通过re模块来实现的。

本文将详细介绍Python中正则表达式的使用方法。

一、基本语法正则表达式是由一些特殊字符和普通字符组成的字符串。

其中,特殊字符用来表示一些特定的模式,普通字符则表示普通的文本。

下面是一些常用的正则表达式特殊字符:1. ^:匹配字符串的开头。

2. $:匹配字符串的结尾。

3. .:匹配任意一个字符。

4. *:匹配前面的字符出现0次或多次。

5. +:匹配前面的字符出现1次或多次。

6. ?:匹配前面的字符出现0次或1次。

7. []:匹配方括号中的任意一个字符。

8. [^]:匹配不在方括号中的任意一个字符。

9. ():将括号中的内容作为一个整体进行匹配。

10. |:匹配左右两边任意一个表达式。

二、常用函数Python中re模块提供了一些常用的函数来操作正则表达式,下面是一些常用的函数:1. re.match(pattern, string, flags=0):从字符串的开头开始匹配,如果匹配成功则返回一个匹配对象,否则返回None。

2. re.search(pattern, string, flags=0):在字符串中查找第一个匹配成功的子串,如果匹配成功则返回一个匹配对象,否则返回None。

3. re.findall(pattern, string, flags=0):在字符串中查找所有匹配成功的子串,返回一个列表。

4. re.sub(pattern, repl, string, count=0, flags=0):将字符串中所有匹配成功的子串替换为repl,返回替换后的字符串。

三、实例演示下面是一些实例演示,展示了正则表达式的使用方法:1. 匹配邮箱地址import reemail='*************'pattern = r'\w+@\w+\.\w+' result = re.match(pattern, email) if result:print(result.group())else:print('匹配失败')2. 匹配手机号码import rephone='138****5678' pattern = r'^1[3-9]\d{9}$' result = re.match(pattern, phone) if result:print(result.group())else:print('匹配失败')3. 查找所有数字import retext = 'abc123def456ghi789' pattern = r'\d+'result = re.findall(pattern, text)print(result)4. 替换字符串中的空格import retext = 'hello world'pattern = r'\s+'result = re.sub(pattern, '-', text)print(result)四、总结本文介绍了Python中正则表达式的基本语法和常用函数,并通过实例演示展示了正则表达式的使用方法。

正则表达式入门教程

正则表达式入门教程以下内容经正则表达式学习网授权≈正则表达式是什么?≈在使用电脑进行各种文字处理的时候,我们有时需要查找和匹配一些特殊的字符串,如邮箱地址、验证用户输入的密码是否包含了大小写字母和数字,查找HTML源文档中的所有web地址等等,这时我们就可以使用到正则表达式。

正则表达式本身是一个“字符串”,通过这个“字符串”去描述字符组成规则。

如abbb、abbbb、abbbbb这三个字符串包都是以a字母开头a后面有一个b字母,而且b字母重复了3到5次。

用正则表达式来描述就是ab{3,5},b{3,5}表示b字符重复3到5次。

如果我们想匹配ababab这样的字符串,ab重复了3次,用正则表达式表示就是(ab){3},圆括号()是正则表达式中的分组。

大家如果想亲自感受正则表达式的使用效果,可以打开正则表达式测试系统。

如以上实例所展示的,正则表达式为人们提供了一种简单易用的字符处理工具。

它在目前主流的文字处理软件中都提供了良好的支持(不仅是编程软件,还有文字处理软件Uedit32、EditPlus,网页采集软件火车头等等),它具有很强的通用性,学好它,我们可以达一变应万变的效果。

≈正则表达式详解≈像{},()这种在正则表达式中,具有特殊含义的字符称为元字符(metacharacter)。

元字符是组成正则表达式的基本元素,在正则表达式经常使用的元字符不是很多,概念容易理解。

大家只要花30来分钟学完我们的教程基本上就可以完全掌握。

为了您能更快速的掌握正则表达式,我们为您推荐一款方便的正则表达式在线测试工具“RegExr”,(RegExr由免费提供)。

保留字符匹配字符本身匹配字符数量匹配字符位置分组匹配表达式选项保留字符(返回目录)在正则表达式中,有一些字符在正则表达式中具有特殊含义被称保留字符,如*表示前一个元素可以重复零次或多次,要匹配“*”字符本身使用\*,半角句号.匹配除了换行符外的所有字符,要匹配“.”使用\.。

正则表达式介绍

正则表达式介绍正则表达式是一种强大的文本处理工具,它用于匹配、查找和替换文本中的模式。

它是一种特殊的语法,可以用于描述字符串的结构和内容。

在日常工作中,我们经常需要处理各种各样的文本数据,比如文本文件、数据库中的数据、网页中的内容等。

而正则表达式正是将这些文本数据进行有效处理的利器。

正则表达式的语法非常丰富,包含了大量的元字符和语法规则。

下面我们就来介绍一些常见的元字符和语法规则。

元字符元字符是正则表达式中的基本单位,它用于表示某种特殊的文本字符或字符集。

下面是一些常见的元字符:1. . :用于匹配任意一个字符,除了换行符(\n)。

2. ^ :用于匹配字符串的开头。

3. $ :用于匹配字符串的结尾。

4. * :用于匹配前面的字符出现0次或多次。

5. + :用于匹配前面的字符出现1次或多次。

6. ? :用于匹配前面的字符出现0次或1次。

7. | :用于表示或者的关系。

语法规则除了元字符之外,正则表达式还包含了许多语法规则。

下面是一些常见的语法规则:1. 字符集:方括号([])内表示要匹配的字符集,可以使用连字符(-)表示范围。

比如[0-9]表示匹配0到9之间的任意数字。

2. 分组:用小括号()来把多个元字符组合起来,形成一个整体。

比如(ab)+表示匹配一个或多个连续的"ab"。

3. 反向引用:用反斜杠(\)加数字来引用前面的分组。

比如(\w)\1表示匹配出现两次的任意单词字符。

4. 贪婪/非贪婪:在元字符后面加上问号(?)可以实现非贪婪模式。

比如.*?表示匹配尽可能少的任意字符。

5. 零宽度断言:用于限定匹配的位置,但不会消耗任何字符。

比如正向预查(?=)表示必须跟着某个模式,但不包含该模式;负向预查(?!)表示必须不跟着某个模式。

应用实例下面我们通过一些实例来演示正则表达式的应用:1. 匹配手机号码:^(13\d|14[579]|15[^4\D]|17[^49\D]|18\d)\d{8}$2. 匹配IP地址:^([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])$3. 匹配邮箱地址:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$4. 匹配HTML标签:<(?:"[^"]*"['"]*|'[^']*'['"]*|[^'">])+>结语正则表达式是一个非常强大的工具,可以用于各种各样的文本处理任务。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

深入浅出之正则表达式第一节理解正则表达式孟岩在程序员日常工作中,数据处理占据了相当的比重。

而在所有的数据之中,文本又占据了相当的比重。

文本能够被人理解,具有良好的透明性,利于系统的开发、测试和维护。

然而,易于被人理解的文本数据,机器处理起来就不一定都那么容易。

文本数据复杂多变,特定性强,甚至是千奇百怪。

因此,文本处理程序可谓生存环境恶劣。

一般来说,文本处理程序都是特定于应用的,一个项目有一个项目的要求,彼此之间很难抽出共同点,代码很难复用,往往是“一次编码,一次运行,到处补丁”。

其程序结构散乱丑陋,谈不上有什么“艺术性”,基本上与“模式”、“架构”什么的无缘。

在这里,从容雅致、温文尔雅派不上用场,要想生存就必须以暴制暴。

事实上,几十年的实践证明,除了正则表达式和更高级的parser技术,在这样一场街头斗殴中别无利器。

而其中,尤以正则表达式最为常用。

所以,对于今天的程序员来说,熟练使用正则表达式着实应该是一种必不可少的基本功。

然而现实情况却是,知道的人很多,善于应用的人却很少,而能够洞悉其原理,理智而高效地应用它的人则少之又少。

大多数开发者被它的外表吓倒,不敢也不耐烦深入了解其原理。

事实上,正则表达式背后的原理并不复杂,只要耐心学习,积极实践,理解正则表达式并不困难。

下面列举的一些条款,来自我本人学习和时间经验的不完全总结。

由于水平和篇幅所限,只能浮光掠影,不足和谬误之处,希望得到有识之士的指教。

1. 了解正则表达式的历史正则表达式萌芽于1940年代的神经生理学研究,由著名数学家StephenKleene第一个正式描述。

具体地说,Kleene归纳了前述的神经生理学研究,在一篇题为《正则集代数》的论文中定义了“正则集”,并在其上定义了一个代数系统,并且引入了一种记号系统来描述正则集,这种记号系统被他称为“正则表达式”。

在理论数学的圈子里被研究了几十年之后,1968年,后来发明了UNIX系统的KenThompson第一个把正则表达式用于计算机领域,开发了qed和 grep两个实用文本处理工具,取得了巨大成功。

在此后十几年里,一大批一流计算机科学家和黑客对正则表达式进行了密集的研究和实践。

在1980年代早期,UNIX运动的两个中心贝尔实验室和加州大学伯克利分校分别围绕grep工具对正则表达式引擎进行了研究和实现。

与之同时,编译器“龙书”的作者 AlfredAho开发了Egrep工具,大大扩展和增强了正则表达式的功能。

此后,他又与《C程序设计语言》的作者BrianKernighan等三人一起发明了流行的awk 文本编辑语言。

到了1986年,正则表达式迎来了一次飞跃。

先是C语言顶级黑客HenrySpencer以源代码形式发布了一个用 C语言写成的正则表达式程序库(当时还不叫opensource),从而把正则表达式的奥妙带入寻常百姓家,然后是技术怪杰LarryWall横空出世,发布了Perl语言的第一个版本。

自那以后,Perl一直是正则表达式的旗手,可以说,今天正则表达式的标准和地位是由Perl塑造的。

Perl5.x 发布以后,正则表达式进入了稳定成熟期,其强大能力已经征服了几乎所有主流语言平台,成为每个专业开发者都必须掌握的基本工具。

2. 掌握一门正则表达式语言使用正则表达式有两种方法,一种是通过程序库,另一种是通过内置了正则表达式引擎的语言本身。

前者的代表是Java、.NET、C/C++、Python,后者的代表则是Perl、Ruby、JavaScript和一些新兴语言,如Groovy等。

如果学习正则表达式的目标仅仅是应付日常应用,则通过程序库使用就可以。

但只有掌握一门正则表达式语言,才能够将正则表达式变成编程的直觉本能,达到较高的水准。

不但如此,正则表达式语言也能够在实践中提供更高的开发和执行效率。

因此,有心者应当掌握一门正则表达式语言。

3. 理解DFA和NFA正则表达式引擎分成两类,一类称为DFA(确定性有穷自动机),另一类称为NFA(非确定性有穷自动机)。

两类引擎要顺利工作,都必须有一个正则式和一个文本串,一个捏在手里,一个吃下去。

DFA 捏着文本串去比较正则式,看到一个子正则式,就把可能的匹配串全标注出来,然后再看正则式的下一个部分,根据新的匹配结果更新标注。

而NFA是捏着正则式去比文本,吃掉一个字符,就把它跟正则式比较,匹配就记下来:“某年某月某日在某处匹配上了!”,然后接着往下干。

一旦不匹配,就把刚吃的这个字符吐出来,一个个的吐,直到回到上一次匹配的地方。

DFA与NFA机制上的不同带来5个影响:(1)DFA 对于文本串里的每一个字符只需扫描一次,比较快,但特性较少;NFA要翻来覆去吃字符、吐字符,速度慢,但是特性丰富,所以反而应用广泛,当今主要的正则表达式引擎,如Perl、Ruby、Python的re模块、Java和.NET的regex库,都是NFA的。

(2)只有NFA才支持lazy和backreference等特性;(3)NFA急于邀功请赏,所以最左子正则式优先匹配成功,因此偶尔会错过最佳匹配结果;DFA 则是“最长的左子正则式优先匹配成功”。

(4)NFA缺省采用greedy量词(见item4);(5)NFA可能会陷入递归调用的陷阱而表现得性能极差。

我这里举一个例子来说明第3个影响。

例如,用正则式/perl ¦ perlman/来匹配文本‘perlmanbook’。

如果是NFA,则以正则式为导向,手里捏着正则式,眼睛看着文本,一个字符一个字符的吃,吃完‘perl’以后,跟第一个子正则式/perl/已经匹配上了,于是记录在案,往下再看,吃进一个‘m’,这下糟了,跟子式/perl/不匹配了,于是把m吐出来,向上汇报说成功匹配‘perl’,不再关心其他,也不尝试后面那个子正则式/perlman/,自然也就看不到那个更好的答案了。

如果是DFA,它是以文本为导向,手里捏着文本,眼睛看着正则式,一口一口的吃。

吃到/p/,就在手里的‘p’上打一个钩,记上一笔,说这个字符已经匹配上了,然后往下吃。

当看到/perl/之后,DFA不会停,会尝试再吃一口。

这时候,第一个子正则式已经山穷水尽了,没得吃了,于是就甩掉它,去吃第二个子正则式的/m/。

这一吃好了,因为又匹配上了,于是接着往下吃。

直到把正则式吃完,心满意足往上报告说成功匹配了‘perlman’。

由此可知,要让NFA正确工作,应该使用/perlman ¦ perl/模式。

通过以上例子,可以理解为什么NFA是最左子式匹配,而DFA是最长左子式匹配。

实际上,如果仔细分析,关于NFA和DFA的不同之处,都可以找出道理。

而明白这些道理,对于有效应用正则表达式是非常有意义的。

4. 理解greedy(贪婪)和lazy(惰性)量词由于日常遇到的正则表达式引擎全都是NFA,所以缺省都采用greedy量词。

Greedy量词的意思不难理解,就是对于/.*/、/\w+/这样的“重复n”次的模式,以贪婪方式进行,尽可能匹配更多字符,直到不得以罢手为止。

举一个例子,以/ <.*> /模式匹配‘ <book> <title> PerlHacks </title> </book> \t’文本,匹配结果不是‘ <book> ’,而是‘ <book> <title> PerlHacks </title> </book> ’。

原因就在于NFA 引擎以贪婪方式执行“重复n次”的命令。

让我们来仔细分析一下这个过程。

条款3指出,NFA的模型是以正则式为导向,拿着正则式吃文本。

在上面的例子里,当它拿着/.*/这个正则式去吃文本的时候,缺省情况下它就这么一路吃下去,即使碰到‘> ’字符也不罢手——既然/./是匹配任意字符,‘> ’当然也可以匹配!所以就尽管吃下去,直到吃完遇到结尾(包括\t字符)也不觉得有什么不对。

这个时候它突然发现,在正则表达式最后还有一个/> /,于是慌了神,知道吃多了,于是就开始一个字符一个字符的往回吐,直到吐出倒数第二个字符‘> ’,完成了与正则式的匹配,才长舒一口气,向上汇报,匹配字符串从第一个字符‘ <’开始,到倒数第二个字符‘> ’结束,即‘ <book> <title> PerlHacks </title> </book> ’。

Greedy 量词的行为有时确实是用户所需要的,有时则不是。

比如在这个例子里,用户可能实际上想得到的是‘book’串。

怎么办呢?这时候lazy量词就派上用场了。

把模式改为/ <.*?> /就可以得到‘book’。

这个加在‘*’号后面的‘?’把greedy量词行为变成lazy量词行为,从而由尽量多吃变为尽量少吃,只要吃到一个‘> ’立刻停止。

问号在正则表达式里用途最广泛,这里是很重要的一个用途。

5. 理解backtracking在条款4的基础上解释backtracking就很容易了。

当NFA发现自己吃多了,一个一个往回吐,边吐边找匹配,这个过程叫做 backtracking(回溯)。

由于存在这个过程,在NFA匹配过程中,特别是在编写不合理的正则式匹配过程中,文本被反复扫描,效率损失是不小的。

明白这个道理,对于写出高效的正则表达式很有帮助。

第二节深入浅出之正则表达式注:JanGoyvaerts为RegexBuddy写的教程的译文前言:半年前我对正则表达式产生了兴趣,在网上查找过不少资料,看过不少的教程,最后在使用一个正则表达式工具RegexBuddy时发现他的教程写的非常好,可以说是我目前见过最好的正则表达式教程。

于是一直想把他翻译过来。

这个愿望直到这个五一长假才得以实现,结果就有了这篇文章。

关于本文的名字,使用“深入浅出”似乎已经太俗。

但是通读原文以后,觉得只有用“深入浅出”才能准确的表达出该教程给我的感受,所以也就不能免俗了。

本文是JanGoyvaerts为RegexBuddy写的教程的译文,版权归原作者所有,欢迎转载。

但是为了尊重原作者和译者的劳动,请注明出处!谢谢!1. 什么是正则表达式基本说来,正则表达式是一种用来描述一定数量文本的模式。

Regex代表RegularExpress。

本文将用<<regex>>来表示一段具体的正则表达式。

一段文本就是最基本的模式,简单的匹配相同的文本。

2. 不同的正则表达式引擎正则表达式引擎是一种可以处理正则表达式的软件。

通常,引擎是更大的应用程序的一部分。

在软件世界,不同的正则表达式并不互相兼容。

相关文档
最新文档