《《正则表达式手册》PPT课件.ppt》由会员分享,可在线阅读,更多相关《《正则表达式手册》PPT课件.ppt(60页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、正则表达式正则表达式CFC4N搜索文件,但只记得其中几个字符搜索文件,只记得一共有几个字符当我是个小白2使用通配符“*”搜索:*.docData Structures.docDatabase.docDatabook.docWindows.doc正在搜索3使用通配符“?”搜索:Data?.docDatabase.docDatabook.doc正在搜索*.docData?.doc使用通配符,可以查找符合指定模式的文件名称。长大后运维:处理故障,抽取有固定格式的日志程序:处理用户输入,是否为合法数据DBA:模糊查询(REGEXP),偶尔也要处理日志当你长大后,你发现*、?这些(通配义字符)已经不能满
2、足你的需求了。情景忘记大写还是小写:hi还是Hi注Hhi(h|H)i搜两遍?试试正则吧7最简单的正则表达式表达式:hi能匹配的字符串(举例):hihimhisthisPhilips8最简单的正则表达式只想要这个结果:hi改成这个:bhibbHhibb(H|h)ib那么只匹配:hi9最简单的正则表达式匹配QQ号:d+匹配结果:10000,1234567,222222,888888810然后呢?bwd()WsS这些都是什么意思?(?)(?=)(?!)(?P)pInname这些又是些什么呢?x4e00-x9fa5x80-xff这些呢?11正则表达式概念!#$%&*&%#%元字符:.除换行以外的其他任
3、意字符s空白字符S除空白字符以外的任意字符w字母、数字、下划线W除了字母、数字、下划线以外的任意字符d数字0-9D除了数字之外的任意字符等等等等b单词边界字符串的开始$字符串结束(?=)环视(零宽断言)后面的字符串符合表达式的时候的位置(?!)*0到无数次+1到无数次?0或者1次n重复N次n,重复至少N次n,mn到m次字符组,字符范围()捕获组(子表达式)等等正则表达式字符组:0-9数字0到数组9之间的任意一个一个a-z字母a到字母z的任意一个cfC除了字母cfC的任意一个字符u4e00-u9fa5汉字中的任意一个汉字注a-z除了字母a到字母z的任意一个字符-a-c除了-字符以及字母a到字母z
4、的任意一个字符|多选分支,或者关系12反向引用.*引用第一个捕获组的结果,用于匹配html的闭合标签表达式Win,匹配字符串Windows的结果是什么呢?表达式ab|cd,能匹配aabd吗?aacd呢?13“”和“$”表达式:hi能匹配:hihimhidden“”代表字符串的开头“$”代表字符串的结束表达式:hi$能匹配:hichiOrochi14“”和“$”表达式hi$只能匹配hi“”代表字符串的开头“$”代表字符串的结束15“”方括号“”匹配指定一堆字符中的一个。表达式:a-zat$能匹配的字符串(举例):catmatzat“”方括号“”匹配指定一堆字符中的一个。表达式:A-Za-zat$
5、能匹配的字符串(举例):CatcatMat“”方括号“”匹配指定一堆字符中的一个。表达式:aeiouat$能匹配的字符串(举例):aateatiat重复符号“+”“+”表示前一字符模式可以被重复1次或n次。表达式:go+gle$能匹配的字符串(举例):goglegooglegooooooooooogle重复符号“+”“+”表示前一字符模式可以被重复1次或n次。表达式:gaeiou+gle$能匹配的字符串(举例):gaglegeglegeaglegeaeeaioueagle20重复符号“*”“”表示前一字符模式可以被重复0次或n次。表达式:go*gle$能匹配的字符串(举例):gglegoogl
6、egooooooooooogle21重复符号“x,y”“x,y”表示前一字符模式可以被重复x到y次。表达式:go2,4gle$能匹配的字符串(仅3个):goooglegooooglegoogle重复符号“x,”“x,”表示前一字符模式可以被重复至少x次。表达式:go2,gle$能匹配的字符串(举例):goooglegooooglegooglegoooooooooooogle子表达式“()”“()”可以指定一堆字符来匹配一个模式。表达式:(very)*large$能匹配的字符串(举例):verylargeveryverylargelargeveryveryveryverylarge分支“|”分支
7、“|”用来指定几个规则只要匹配一个规则即成匹配。表达式:com$|org$|net$能匹配的字符串(仅3个):comorgnet分支“|”分支“|”用来指定几个规则只要匹配一个规则即成匹配。表达式:abc.(com|org|net)$能匹配的字符串(仅3个):转义符号“”如果要匹配“”“”“+”“)”等等有特殊含义的字符,可以用“”做转义。表达式:1*(2+3)=6$能匹配的字符串(仅1个):1*(2+3)=6小试身手匹配带区号、横杠的电话号码匹配第一位可能带0的那种手机号码匹配IP匹配日期(1-31号)PHP的面试题表达式phper(.+),字符串是phper001,phper002,php
8、er003,那么捕获结果的1组里是什么?Q&A结束刚刚开始29正则起源与流派1940神经学家研究出一种模型,认为神经系统在神经元层面上就是这样工作的。N年后数学家描述正则集合(regularsets)1968年KenThompson的文章regualr.描述一种正则表达式编译器,该编译器生成IBM7094的OBJECT代码,也诞生了他的qed,也就是后来的UNIX中ed编辑器的基础ed没qed先进,他有个命令是这样g/RegularExpresion/p成为独立的工具grep(以及拓展的egrep)30两种不同引擎qed-erep-EgrepawklexsedPOSIXPerl正则的起源与流派
9、DFADeterministicfiniteautomaton确定型有穷自动机NFANon-deterministicfiniteautomaton非确定型有穷自动机TraditionalNFAPOSIXNFA31DFA与NFA的区别DFA引擎因为不需要回溯,所以匹配快速,但不支持捕获组,所以也就不支持反向引用和$number这种引用方式,目前使用DFA引擎的语言和工具主要有awk、egrep和lex。POSIXNFA主要指符合POSIX标准的NFA引擎,它的特点主要是提供longest-leftmost匹配,也就是在找到最左侧最长匹配之前,它将继续回溯。同DFA一样,非贪婪模式或者说忽略优先
10、量词对于POSIXNFA同样是没有意义的。大多数语言和工具使用的是传统型的NFA引擎,它有一些DFA不支持的特性:捕获组、反向引用和$number引用方式;环视(Lookaround,(?=)、(?)。本次培训只讨论标准本次培训只讨论标准NFA引擎引擎32匹配基础规则有限选择最左端匹配结果标准量词优先匹配33为啥要了解“这么深入”?网页小偷程序(100k内容PHP就超时)url重写(apachenginx对url处理了2ms)日志分析(1G日志处理了1天)想自己写个像python、php一样的语言想开发自己的DB,想知道DB语法分析器执行原理本来就是个爱钻研的人遇到以上情况,或者符合其中一条的
11、,请继续字符串组成cf位置0位置1位置2字符1字符035占有字符与零宽度正则表达式匹配过程中,如果子表达式匹配到的是字符内容,而非位置,并被保存到最终的匹配结果中,那么就认为这个子表达式是占有字符的;如果子表达式匹配的仅仅是位置,或者匹配的内容并不保存到最终的匹配结果中,那么就认为这个子表达式是零宽度的。占有字符是互斥的,零宽度是非互斥的。也就是一个字符,同一时间只能由一个子表达式匹配,而一个位置,却可以同时由多个零宽度的子表达式匹配。36控制权和传动控制权和传动 正则的匹配过程,通常情况下都是由一个子表达式(可能为一个普通字符、元字符或元字符序列组成)取得控制权,从字符串的某一位置开始尝试匹
12、配,一个子表达式开始尝试匹配的位置,是从前一子表达匹配成功的结束位置开始的。如正则表达式:(子表达式一)(子表达式二)假设(子表达式一)为零宽度表达式,由于它匹配开始和结束的位置是同一个,如位置0,那么(子表达式二)是从位置0开始尝试匹配的。假设(子表达式一)为占有字符的表达式,由于它匹配开始和结束的位置不是同一个,如匹配成功开始于位置0,结束于位置2,那么(子表达式二)是从位置2开始尝试匹配的。而对于整个表达式来说,通常是由字符串位置0开始尝试匹配的。如果在位置0开始的尝试,匹配到字符串某一位置时整个表达式匹配失败,那么引擎会使正则向前传动,整个表达式从位置1开始重新尝试匹配,依此类推,直到
13、报告匹配成功或尝试到最后一个位置后报告匹配失败。简单的匹配过程源字符串:abc正则表达式:abc匹配过程:首先由字符“a”取得控制权,从位置0开始匹配,由“a”来匹配“a”,匹配成功,控制权交给字符“b”;由于“a”已被“a”匹配,所以“b”从位置1开始尝试匹配,由“b”来匹配“b”,匹配成功,控制权交给“c”;由“c”来匹配“c”,匹配成功。此时正则表达式匹配完成,报告匹配成功。匹配结果为“abc”,开始位置为0,结束位置为3。38含有匹配优先量词的匹配过程含有匹配优先量词的匹配过程(成功成功)源字符串:abc正则表达式:ab?c量词“?”属于匹配优先量词,在可匹配可不匹配时,会先选择尝试匹
14、配,只有这种选择会使整个表达式无法匹配成功时,才会尝试让出匹配到的内容。这里的量词“?”是用来修饰字符“b”的,所以“b?”是一个整体。匹配过程:首先由字符“a”取得控制权,从位置0开始匹配,由“a”来匹配“a”,匹配成功,控制权交给字符“b?”;由于“?”是匹配优先量词,所以会先尝试进行匹配,由“b?”来匹配“b”,匹配成功,控制权交给“c”,同时记录一个备选状态;由“c”来匹配“c”,匹配成功。记录的备选状态丢弃。此时正则表达式匹配完成,报告匹配成功。匹配结果为“abc”,开始位置为0,结束位置为3。零宽度匹配过程零宽度匹配过程源字符串:a12正则表达式:(?=a-z)a-z0-9+$元字
15、符“”和“$”匹配的只是位置,顺序环视“(?=a-z)”只进行匹配,并不占有字符,也不将匹配的内容保存到最终的匹配结果,所以都是零宽度的。这个正则的意义就是匹配由字母或数字组成的,第一个字符是字母的字符串。40匹配过程:首先由元字符“”取得控制权,从位置0开始匹配,“”匹配的就是开始位置“位置0”,匹配成功,控制权交给顺序环视“(?=a-z)”“(?=a-z)”要求它所在位置右侧必须是字母才能匹配成功,零宽度的子表达式之间是不互斥的,即同一个位置可以同时由多个零宽度子表达式匹配,所以它也是从位置0尝试进行匹配,位置0的右侧是字符“a”,符合要求,匹配成功,控制权交给“a-z0-9+”;因为“(
16、?=a-z)”只进行匹配,并不将匹配到的内容保存到最后结果,并且“(?=a-z)”匹配成功的位置是位置0,所以“a-z0-9+”也是从位置0开始尝试匹配的,“a-z0-9+”首先尝试匹配“a”,匹配成功,继续尝试匹配,可以成功匹配接下来的“1”和“2”,此时已经匹配到位置3,位置3的右侧已没有字符,这时会把控制权交给“$”;元字符“$”从位置3开始尝试匹配,它匹配的是结束位置,也就是“位置3”,匹配成功。此时正则表达式匹配完成,报告匹配成功。匹配结果为“a12”,开始位置为0,结束位置为3。其中“”匹配位置0,“(?=a-z)”匹配位置0,“a-z0-9+”匹配字符串“a12”,“$”匹配位置
17、3。41匹配优先表达式:.+字符串:testtesttesttest匹配过程是什么?如果是.+?呢?如何选择使用量词优先,还是忽略优先量词?还是占有优先量词?(.+)茅塞顿开PHP的面试题表达式phper(.+),字符串是phper001,phper002,phper003,那么捕获结果的1组里是什么?现在知道了吗?为什么是这个结果?43回溯备份状态当正则遇到优先量词时,遇到“?”,会先记录备份状态,当下一个匹配失败的时候,回到这里,再进行匹配。字符串:test1xxxxxxxxxtest(星号处是10W个字符)表达式:.+?(想要的结果是每个闭合的div为一组)分析一下引擎会记录多少个备选状
18、态?第一个备选状态是几个字符?第二个呢?第3 4 5个呢?第n个呢?一共多少个字符呢?占多大内存?44一个例子DB中有个字段使用了浮点数,需要程序处理。需求是保留小数点后面3位,如果最后一位是0,则保留两位。字符例子:15.214123、37.500232、154.356目的:15.21437.50表达式:?(.dd1-9?)d*$1d*改成d+(.dd1-9?)d+$145占有优先量词与固化分组*+、+、?+匹配过程如何?上个例子如何解决?.(dd(?1-9?)d+46捕获组与反向引用捕获组()()是子表达式的标识,同时,匹配结果会保存起来,最后一同给出。在表达式中可以直接引用。比如表达式用
19、来匹配字符串和,结果中1分别是和”彪悍的例子表达式:(a-z0-9)+字符串:1W个字符引擎会捕获多少个组呢?捕获不分组(?:)47其他递归条件判断字符编码语言特性修饰符NFA表达式主导、DFA文字主导没想起来的。48精确高效QQ号的匹配 d+Ip的匹配 d+.d+.d+.d+日期匹配 dd如何改进?如何改进?误匹配漏匹配49语言特性PHPPYTHON的环视不支持不确定长度(?=0-9+),.NET支持。JAVASCRIPT连环视都不支持50先粗后细,先加后减 使用正则表达式语法对于目标文本进行描述和界定,可以像画素描一样,先大致勾勒出框架,再逐步在局步实现细节。仍举刚才的手机号的例子,先界定
20、d11,总不会错;再细化为1358d9,就向前迈了一大步(至于第二位是不是3、5、8,这里无意深究,只举这样一个例子,说明逐步细化的过程)。这样做的目的是先消除漏匹配(刚开始先尽可能多地匹配,做加法),然后再一点一点地消除误匹配(做减法)。这样有先有后,在考虑时才不易出错,从而向“不误不漏”这个目标迈进。51明确需求明确需求具体说来,就是谨慎用点号这样的元字符,尽可能不用星号和加号这样的任意量词。只要能确定范围的,例如w,就不要用点号;只要能够预测重复次数的,就不要用任意量词。例如,写析取twitter消息的脚本,假设一条消息的xml正文部分结构是且正文中无尖括号,那么1,480这种写法的思路
21、要好于.*原因有二:一是使用,它保证了文本的范围不会超出下一个小于号所在的位置;二是明确长度范围,1,480,其依据是一条twitter消息大致能的字符长度范围。当然,480这个长度是否正确还可推敲,但是这种思路是值得借鉴的。说得狠一点,“滥用点号、星号和加号甚至括号是不环保、不负责任的做法”。不要让稻草压死骆驼不要让稻草压死骆驼每使用一个普通括号()而不是非捕获型括号(?:),就会保留一部分内存等着你再次访问。这样的正则表达式、无限次地运行次数,无异于一根根稻草的堆加,终于能将骆驼压死。养成合理使用(?:)括号的习惯。53少用多选分支caft与c(a|b|c|d|e|f)t6次回溯(回溯的主
22、要原因)适当使用边界字符btheb匹配the不匹配there$等分支顺序可以选择字符串中最常出现的字符串放到分支最前面54系统内部的优化字符串连接abc当作一个元素,避免三次迭代化简量词优化.*跟(?:.)*匹配结果一致,但前效率更高消除不必要括号如上,它会用前者代替后者消除不必要的字符组.中就一个字符,会被优化为.过度回溯检测前面提到过PHP限制回溯次数的截图默认10W次量词等价转换dddd 跟d4哪个效率高?前者4个元素,后者一个元素55正则应用原理表达式编译检查语法,并编译为内部形式传动开始定位至字符串起始位置元素检测相连元素、量词修饰符、控制权寻找匹配结果NFA找到后锁定,返回。DFA继续下一个,找最长结果传动装置的驱动过程没匹配成功,从下一个字符开始匹配彻底失败所有字符尝试完毕,返回彻底失败小试身手抓取php.ini中所有配置参数参考答案:检测PHP代码中危险函数指令(扫描webshell)参考答案:抓取页面所有a标签中链接地址(不符合W3C标准)写一款SQL语法分析器,拦截危险SQL57高手的境界心中无引擎,眼里无流派心中无引擎,眼里无流派工具工具地址59Q&A完参考资料:CNXCT:http/(我自己)雁过无痕:http:/我爱正则表达式:BenzBus:http:/(PPT模版背景作者)