正则表达式讲义课件

上传人:痛*** 文档编号:241515734 上传时间:2024-07-01 格式:PPTX 页数:45 大小:154.92KB
返回 下载 相关 举报
正则表达式讲义课件_第1页
第1页 / 共45页
正则表达式讲义课件_第2页
第2页 / 共45页
正则表达式讲义课件_第3页
第3页 / 共45页
点击查看更多>>
资源描述
正则表达式Jameson Jin7/1/202411.什么是正什么是正则表达式表达式正则表达式是一种用来描述一定数量文本的模式。Regex代表RegularExpress。正则表达式引擎是一种可以处理正则表达式的软件。不同的正则表达式并不互相兼容。Perl5类型的引擎是应用最广泛的引擎。许多近代的引擎都很类似,但不完全一样。例如.NET正则库,JDK正则包。7/1/202422.文字符号文字符号最基本的正则表达式由单个文字符号组成。如a,它将匹配字符串中第一次出现的字符“a”。如对字符串“Jackisaboy”。“J”后的“a”将被匹配。而第二个“a”将不会被匹配。正则表达式也可以匹配第二个“a”,会有一个函数可以使你从前一次匹配的位置开始继续向后搜索。cat会匹配“Aboutcatsanddogs”中的“cat”。这等于是告诉正则表达式引擎,找到一个c,紧跟一个a,再跟一个t。要注意,正则表达式引擎缺省是大小写敏感的。7/1/202432.1.特殊字符对于文字字符,有12个字符被保留作特殊用途。$.|?*+()这些特殊字符也被称作元字符,不是任何情况下都是特殊字符。如果你想在正则表达式中将这些字符用作文本字符,你需要用反斜杠“”对其进行换码。匹配“1+1=2”,正确的表达式为1+1=21+1=2则匹配至少1个1之后跟着1=27/1/202442.2.不可显示字符t代表Tab(0 x09)r代表回车符(0 x0D)n代表换行符(0 x0A)要注意的是Windows中文本文件使用“rn”来结束一行而Unix使用“n”。7/1/202453.正正则表达式引擎的内部工作机制表达式引擎的内部工作机制两种引擎:文本导向(text-directed)的引擎和正则导向(regex-directed)的引擎,主要介绍正则导向。正则导向独有特性:惰性、反向引用等。正则表达式regex|regexnot应用到字符串“regexnot”。如果匹配的结果是regex,则引擎是正则导向的。如果结果是regexnot,则是文本导向的。正则导向,找到就不再找了,惰性,返回最左边的匹配结果。文本导向,找最符合条件的。7/1/202464.字符集字符集字符集是由一对方括号“”括起来的字符集合。使用字符集,仅仅匹配多个字符中的一个。匹配一个“a”或一个“e”,使用ae字符集中的字符顺序并没有什么关系,结果都是相同的。可以使用连字符“-”定义一个字符范围作为字符集。0-9匹配0到9之间的单个数字0-9a-fA-F匹配单个的十六进制数字,并且大小写不敏感。7/1/202474.1.字符集的一些应用查找一个可能有拼写错误的单词sepaeraete或licsencse。查找程序语言的标识符A-Za-z_A-Za-z_0-9*查找C风格的十六进制数0 xXA-Fa-f0-9+7/1/202484.2.取反字符集在左方括号“”后面紧跟一个尖括号“”,将会对字符集取反。结果是字符集将匹配任何不在方括号中的字符。取反字符集必须要匹配一个字符。qu并不意味着:匹配一个q,后面没有u跟着。它意味着:匹配一个q,后面跟着一个不是u的字符。所以它不会匹配“Iraq”中的q,而会匹配“Iraqisacountry”中的q和一个空格符。事实上,空格符是匹配中的一部分,因为它是一个“不是u的字符”。如果你只想匹配一个q,条件是q后面有一个不是u的字符,可以用后面将讲到的向前查看来解决。7/1/202494.3.字符集中的元字符在字符集中只有4个字符具有特殊含义。-代表字符集定义的结束;代表转义;代表取反;-代表范围定义。其他常见的元字符在字符集定义内部都是正常字符,不需要转义。如果对那些通常的元字符进行转义,一样会生效,但是会降低可读性。在字符集定义中为了将反斜杠“”作为一个文字字符而非特殊含义的字符,你需要用另一个反斜杠对它进行转义。-都可以用反斜杠进行转义,或者将他们放在一个不可能使用到他们特殊含义的位置。字符“”,不将它放在除了左括号“”后面的位置x会匹配一个“”或“x”-x或x-都会匹配一个“-”或“x”7/1/2024104.4.字符集的简写d代表0-9w代表单词字符A-Za-z0-9_s代表“白字符”,包含了空格符和Tab符,以及回车换行符rn字符集的缩写形式可以用在方括号之内或之外S代表sW代表wD代表d7/1/2024114.5.字符集的重复如果用?*+操作符来重复一个字符集,将会重复整个字符集。而不仅是它匹配的那个字符。正则表达式0-9+会匹配837以及222。如果仅仅想重复被匹配的那个字符,可以用向后引用达到目的。7/1/2024125.使用使用?*或或+进行重复行重复?匹配前导字符0次或一次。事实上是表示前导字符是可选的。+告诉引擎匹配前导字符1次或多次*告诉引擎匹配前导字符0次或多次匹配没有属性的HTML标签7/1/2024135.1.限制性重复许多现代的正则表达式实现,都允许你定义对一个字符重复多少次。词法是:min,max。min和max都是非负整数。如果逗号有而max被忽略了,则max没有限制如果逗号和max都被忽略了,则重复min次0,和*一样1,和+一样。b1-90-93b匹配10009999之间的数字b1-90-92,4b匹配一个在10099999之间的数字7/1/2024145.2.贪婪性假设你想用一个正则表达式匹配一个HTML标签。在两个尖括号之间的内容,就应该是一个HTML标签。首先想到用正则表达式对于测试字符串,“Thisisafirsttest”,期望会返回,然后继续进行匹配的时候,返回。正则表达式将会匹配“first”。原因在于“+”是贪婪的。也就是说,“+”会导致正则表达式引擎试图尽可能的重复前导字符。只有当这种重复会引起整个正则表达式匹配失败的情况下,引擎会进行回溯。也就是说,它会放弃最后一次的“重复”,然后处理正则表达式余下的部分。和“+”类似,“?*”的重复也是贪婪的。7/1/2024155.2.1.深入正则表达式引擎内部第一个记号是“”。到目前为止,“.+”已经匹配了“firsttest”。引擎会试图将“”与换行符进行匹配,结果失败了。于是引擎进行回溯。结果是现在“.+”匹配“firsttes”。于是引擎将“”与“t”进行匹配。显然还是会失败。这个过程继续,直到“.+”匹配“first”与“”匹配。于是引擎找到了一个匹配“first”。正则导向的引擎是“急切的”,所以它会急着报告它找到的第一个匹配。而不是继续回溯,即使可能会有更好的匹配,例如“”。所以我们可以看到,由于“+”的贪婪性,使得正则表达式引擎返回了一个最左边的最长的匹配。7/1/2024165.2.2.用懒惰性取代贪婪性一个用于修正以上问题的可能方案是用“+”的惰性代替贪婪性。你可以在“+”后面紧跟一个问号“?”来达到这一点。“*”,“”和“?”表示的重复也可以用这个方案。因此在上面的例子中我们可以使用正则表达式记号“”会匹配字符串的第一个“”匹配“M”,结果失败了。引擎会进行回溯,和上一个例子不同,因为是惰性重复,所以引擎是扩展惰性重复而不是减少,于是“.+”现在被扩展为“”。这次得到了一个成功匹配。引擎于是报告“”是一个成功的匹配。7/1/2024175.2.3.惰性扩展的一个替代方案一个更好的替代方案。用一个贪婪重复与一个取反字符集:+使用惰性重复时,引擎会在找到一个成功匹配前对每一个字符进行回溯。而使用取反字符集则不需要进行回溯。文本导向的引擎是不回溯的。但是同时他们也不支持惰性重复操作。7/1/2024186.使用使用“.”匹配几乎任意字符匹配几乎任意字符在正则表达式中,“.”是最常用的符号之一。也是最容易被误用的符号之一。“.”匹配一个单个的字符而不用关心被匹配的字符是什么。唯一的例外是新行符。在缺省情况下,“.”等于是字符集nr(Window)或n(Unix)的简写。要使“.”匹配所有的字符,包括新行符。在Perl中,“.”可以匹配新行符的模式被称作“单行模式”。在.NETFramework中激活单行模式:Regex.Match(“string”,”regex”,RegexOptions.SingleLine)7/1/2024196.1.保守的使用点号“.”点号可以说是最强大的元字符。用一个点号,就能匹配几乎所有的字符。也常常会匹配不该匹配的字符。匹配一个具有“mm/dd/yy”格式的日期,但是允许用户来选择分隔符。一个方案是dd.dd.dd能匹配日期“02/12/03”,但02512703也会被认为是一个有效的日期dd-/.dd-/.dd会匹配“99/99/99”0-1d-/.0-3d-/.dd会匹配“19/39/99”正则表达式达到如何完美的程度取决于想达到什么样的目的7/1/2024207.字符串开始和字符串开始和结束的束的锚定定锚定和一般的正则表达式符号不同,它不匹配任何字符。相反,他们匹配的是字符之前或之后的位置。“”匹配一行字符串第一个字符前的位置。a将会匹配字符串“abc”中的ab将不会匹配“abc”中的任何字符$匹配字符串中最后一个字符的后面的位置。c$匹配“abc”中的c。7/1/2024217.1.锚定的应用如果想校验用户的输入为整数,用d+$。用户输入中,常常会有多余的前导空格或结束空格。可以用s*和s*$来匹配前导空格或结束空格7/1/2024227.2.使用“”和“$”作为行的开始和结束锚定一个包含了多行的字符串。“firstlinenrsecondline”(其中nr表示一个新行符)。常常需要对每行分别处理而不是整个字符串。几乎所有的正则表达式引擎都提供一个选项,可以扩展这两种锚定的含义。可以匹配字串的开始位置(在f之前),以及每一个新行符的后面位置(在nr和s之间)。$会匹配字串的结束位置(最后一个e之后),以及每个新行符的前面(在e与nr之间)。在.NET中,定义锚定匹配每一个新行符的前面和后面位置:Regex.Match(string,regex,RegexOptions.Multiline)stringstr=Regex.Replace(Original,RegexOptions.Multiline)-将会在每行的行首插入“”。7/1/2024237.3.绝对锚定A只匹配整个字符串的开始位置,Z只匹配整个字符串的结束位置。即使使用了“多行模式”,A和Z也从不匹配新行符。即使Z和$只匹配字符串的结束位置,仍然有一个例外的情况。如果字符串以新行符结束,则Z和$将会匹配新行符前面的位置,而不是整个字符串的最后面。如果应用a-z+$到“joen”,则匹配结果是“joe”而不是“joen”。7/1/2024248.单词边界界元字符b是一种对位置进行匹配的“锚”。这种匹配也是0长度匹配。有4种位置被认为是“单词边界”:在字符串的第一个字符前的位置(如果字符串的第一个字符是一个“单词字符”)在字符串的最后一个字符后的位置(如果字符串的最后一个字符是一个“单词字符”)在一个“单词字符”和“非单词字符”之间,其中“非单词字符”紧跟在“单词字符”之后在一个“非单词字符”和“单词字符”之间,其中“单词字符”紧跟在“非单词字符”后面“单词字符”是可以用“w”匹配的字符,“非单词字符”是可以用“W”匹配的字符。b4b能够匹配单个的4而不是一个更大数的一部分。这个正则表达式不会匹配“44”中的4。换种说法,b匹配一个“字母数字序列”的开始和结束的位置。“单词边界”的取反集为B,要匹配的位置是两个“单词字符”之间或者两个“非单词字符”之间的位置。7/1/2024258.1.深入正则表达式引擎内部把正则表达式bisb应用到字符串“Thisislandisbeautiful”。引擎先处理符号b。因为b是0长度,所以第一个字符T前面的位置会被考察。因为T是一个“单词字符”,而它前面的字符是一个空字符(void),所以b匹配了单词边界。接着i和第一个字符“T”匹配失败。匹配过程继续进行,直到第五个空格符,和第四个字符“s”之间又匹配了b。然而空格符和i不匹配。继续向后,到了第六个字符“i”,和第五个空格字符之间匹配了b,然后is和第六、第七个字符都匹配了。然而第八个字符和第二个“单词边界”不匹配,所以匹配又失败了。到了第13个字符i,因为和前面一个空格符形成“单词边界”,同时is和“is”匹配。引擎接着尝试匹配第二个b。因为第15个空格符和“s”形成单词边界,所以匹配成功。引擎返回成功匹配的结果。7/1/2024269.选择符符正则表达式中“|”表示选择。用选择符匹配多个可能的正则表达式中的一个。如果你想搜索文字“cat”或“dog”,可以用cat|dog选择符在正则表达式中具有最低的优先级可以用圆括号来限制选择符的作用范围b(cat|dog)b,这样正则引擎把(cat|dog)当成一个正则表达式单位来处理7/1/2024279.1.注意正则引擎的“急于表功”性正则引擎是急切的,当找到一个有效的匹配时,会停止搜索。因此在一定条件下,选择符两边的表达式的顺序对结果会有影响。假设用正则表达式搜索一个编程语言的函数列表:Get,GetValue,Set或SetValue。Get|GetValue|Set|SetValue。当搜索SetValue时,因为Get和GetValue都失败了,而Se匹配成功。会返回第一个成功的匹配,就是“Set”,而不是“SetValue”改变选项的顺序,使用GetValue|Get|SetValue|Set,就可以优先搜索最长的匹配。可以把四个选项结合起来成两个选项:Get(Value)?|Set(Value)?一个更好的方案是使用单词边界:b(Get|GetValue|Set|SetValue)b或b(Get(Value)?|Set(Value)?b更进一步,b(Get|Set)(Value)?b7/1/20242810.组与向后引用与向后引用把正则表达式的一部分放在圆括号内,你可以将它们形成组。然后可以对整个组使用一些正则操作只有圆括号“()”才能用于形成组。“”用于定义字符集。“”用于定义重复操作。当用“()”定义了一个正则表达式组后,正则引擎则会把被匹配的组按照顺序编号,存入缓存。当对被匹配的组进行向后引用的时候,可以用“数字”的方式进行引用。1引用第一个匹配的后向引用组,2引用第二个组,以此类推,n引用第n个组。0则引用整个被匹配的正则表达式本身。假设想匹配一个HTML标签的开始标签和结束标签,以及标签中间的文本。Thisisatest,要匹配和以及中间的文字。可以用如下正则表达式:*.*?首先,“”将会匹配“”的第一个字符“”的字符。最后正则表达式的“”将会匹配“”的“”。接下来正则引擎将对结束标签之前的字符进行惰性匹配,直到遇到一个“/”符号。然后正则表达式中的“1”表示对前面匹配的组“(A-ZA-Z0-9*)”进行引用,被引用的是标签名“B”。所以需要被匹配的结尾标签为“”7/1/202429可以对相同的后向引用组进行多次引用,(a-c)x1x1将匹配“axaxa”、“bxbxb”以及“cxcxc”。如果用数字形式引用的组没有有效的匹配,则引用到的内容简单的为空。一个后向引用不能用于它自身。(abc1)是错误的不能将0用于一个正则表达式匹配本身,它只能用于替换操作中。后向引用不能用于字符集内部。(a)1b中的1并不表示后向引用。向后引用会降低引擎的速度,因为它需要存储匹配的组。如果不需要向后引用,可以告诉引擎对某个组不存储。Get(?:Value)其中“(”后面紧跟的“?:”会告诉引擎对于组(Value),不存储匹配的值以供后向引用。7/1/20243010.1.重复操作与后向引用当对组使用重复操作符时,缓存里后向引用内容会被不断刷新,只保留最后匹配的内容。(abc+)=1将匹配“cab=cab”(abc)+=1却不会。因为(abc)第一次匹配“c”时,“1”代表“c”;然后(abc)会继续匹配“a”和“b”。最后“1”代表“b”,所以它会匹配“cab=b”。应用:检查重复单词-当编辑文字时,很容易就会输入重复单词,例如“thethe”。使用b(w+)s+1b可以检测到这些重复单词。7/1/20243110.2.组的命名和引用在PHP,Python中,用(?Pgroup)来对组进行命名。?P就是对组(group)进行了命名。其中name是对组的起的名字。可以用(?P=name)进行引用。.NET的命名组(?group)(?secondgroup).NET提供两种词法来创建命名组:一是用尖括号“”,或者用单引号“”。尖括号在字符串中使用更方便,单引号在ASP代码中更有用,因为ASP代码中“”被用作HTML标签。要引用一个命名组,使用k或kname.当进行搜索替换时,可以用“$name”来引用一个命名组。7/1/20243211.正正则表达式的匹配模式表达式的匹配模式/i使正则表达式对大小写不敏感,/s开启“单行模式”,即点号“.”匹配新行符/m开启“多行模式”,即“”和“$”匹配新行符的前面和后面的位置。如果在正则表达式内部插入修饰符(?ism),则该修饰符只对其右边的正则表达式起作用。(?-i)是关闭大小写不敏感。(?i)te(?-i)st应该匹配TEst,但是不能匹配teST或TEST.7/1/20243312.原子原子组与防止回溯与防止回溯在一些特殊情况下,回溯会使得引擎的效率极其低下。要匹配这样的字串,字串中的每个字段间用逗号做分隔符,第12个字段由P开头。(.*?,)11P这个正则表达在极端情况下,如果第12个字段不是由P开头,则会发生灾难性的回溯。如要搜索的字串为“1,2,3,4,5,6,7,8,9,10,11,12,13”。首先,正则表达式一直成功匹配直到第12个字符。这时,前面的正则表达式消耗的字串为“1,2,3,4,5,6,7,8,9,10,11,”,到了下一个字符,P并不匹配“12”。所以引擎进行回溯,这时正则表达式消耗的字串为“1,2,3,4,5,6,7,8,9,10,11”。继续下一次匹配过程,下一个正则符号为点号.,可以匹配下一个逗号“,”。然而,并不匹配字符“12”中的“1”。匹配失败,继续回溯。这样的回溯组合是个非常大的数量。因此可能会造成引擎崩溃。用取反字符集代替点号。(,rn*,)11P可以使失败回溯的次数下降到11次。7/1/202434原子组的目的是使正则引擎失败的更快一点。可以有效的阻止海量回溯。原子组的语法是(?正则表达式)位于(?)之间的所有正则表达式都会被认为是一个单一的正则符号。一旦匹配失败,引擎将会回溯到原子组前面的正则表达式部分。前面的例子用原子组可以表达成(?(.*?,)11)P。一旦第十二个字段匹配失败,引擎回溯到原子组前面的7/1/20243513.向前向前查看与向后看与向后查看看“向前查看”和“向后查看”也被称作“零长度断言”。和锚定一样都是零长度的(所谓零长度即指该正则表达式不消耗被匹配的字符串)。不同之处在于“前后查看”会实际匹配字符,只是他们会抛弃匹配只返回匹配结果:匹配或不匹配。他们并不实际消耗字符串中的字符,而只是断言一个匹配是否可能。7/1/20243613.1.肯定和否定式的向前查看7/1/202437要查找一个q,后面没有紧跟一个u。也就是说,要么q后面没有字符,要么后面的字符不是u。采用否定式向前查看:q(?!u)否定式向前查看的语法是(?!查看的内容)肯定式向前查看和否定式向前查看很类似:(?=查看的内容)如果在“查看的内容”部分有组,也会产生一个向后引用。但是向前查看本身并不会产生向后引用,也不会被计入向后引用的编号中。向前查看本身是会被抛弃掉的,只保留匹配与否的判断结果。如果你想保留匹配的结果作为向后引用,可以用(?=(regex)来产生一个向后引用。13.2.肯定和否定式的先后查看7/1/202438否定式向后查看的语法是:(?!查看内容)肯定式向后查看的语法是:(?=查看内容)和向前查看相比,多了一个表示方向的左尖括号。(?!a)b将会匹配一个没有“a”作前导字符的“b”。向前查看从当前字符串位置开始对“查看”正则表达式进行匹配;向后查看则从当前字符串位置开始先后回溯一个字符,然后再开始对“查看”正则表达式进行匹配。13.3.深入正则表达式引擎内部7/1/202439把正则表达式q(?!u)应用到字符串“Iraq”。正则表达式的第一个符号是q当第四个字符“q”被匹配后,“q”后面是空字符(void)。而下一个正则符号是向前查看。引擎注意到已经进入了一个向前查看正则表达式部分。下一个正则符号是u,和空字符不匹配,从而导致向前查看里的正则表达式匹配失败。因为是一个否定式的向前查看,意味着整个向前查看结果是成功的。于是匹配结果“q”被返回了。把相同的正则表达式应用到“quit”。q匹配了“q”。下一个正则符号是向前查看部分的u它匹配了字符串中的第二个字符“i”。引擎继续走到下个字符“i”。然而引擎这时注意到向前查看部分已经处理完了,并且向前查看已经成功。于是引擎抛弃被匹配的字符串部分,这将导致引擎回退到字符“u”。因为向前查看是否定式的,意味着查看部分的成功匹配导致了整个向前查看的失败,因此引擎不得不进行回溯。最后因为再没有其他的“q”和q匹配,所以整个匹配失败了。7/1/202440把q(?=u)i应用到“quit”。q首先匹配“q”。然后向前查看成功匹配“u”,匹配的部分被抛弃,只返回可以匹配的判断结果。引擎从字符“i”回退到“u”。由于向前查看成功了,引擎继续处理下一个正则符号i。结果发现i和“u”不匹配。因此匹配失败了。由于后面没有其他的“q”,整个正则表达式的匹配失败了。13.4.更进一步理解正则表达式引擎内部机制7/1/202441把(?=a)b应用到“thingamabob”。引擎开始处理向后查看部分的正则符号和字符串中的第一个字符。向后查看告诉正则表达式引擎回退一个字符,然后查看是否有一个“a”被匹配。因为在“t”前面没有字符,所以引擎不能回退。因此向后查看失败了。引擎继续走到下一个字符“h”。再一次,引擎暂时回退一个字符并检查是否有个“a”被匹配。结果发现了一个“t”。向后查看又失败了。向后查看继续失败,直到正则表达式到达了字符串中的“m”,于是肯定式的向后查看被匹配了。因为它是零长度的,字符串的当前位置仍然是“m”。下一个正则符号是b,和“m”匹配失败。下一个字符是字符串中的第二个“a”。引擎向后暂时回退一个字符,并且发现a不匹配“m”。再下一个字符是字符串中的第一个“b”。引擎暂时性的向后退一个字符发现向后查看被满足了,同时b匹配了“b”。因此整个正则表达式被匹配了。作为结果,正则表达式返回字符串中的第一个“b”。13.5.向前向后查看的应用7/1/202442查找一个具有6位字符的,含有“cat”的单词。catw3|wcatw2|w2catw|w3cat有两个基本需求要满足:一是我们需要一个6位的字符,二是单词含有“cat”。满足第一个需求的正则表达式为bw6b满足第二个需求的正则表达式为bw*catw*b把两者结合起来,(?=bw6b)bw*catw*bb(?=w6b)w0,3catw*14.正正则表达式中的条件表达式中的条件测试7/1/202443条件测试的语法为(?ifthen|else)“if”部分可以是向前向后查看表达式。如果用向前查看,则语法变为:(?(?=regex)then|else),其中else部分是可选的。如果if部分为true,则正则引擎会试图匹配then部分,否则引擎会试图匹配else部分。向前先后查看并不实际消耗任何字符,因此后面的then与else部分的匹配时从if测试前的部分开始进行尝试。15.为正正则表达式添加注表达式添加注释7/1/202444在正则表达式中添加注释的语法是:(?#comment)为用于匹配有效日期的正则表达式添加注释:(?#year)(19|20)dd-/.(?#month)(01-9|1012)-/.(?#day)(01-9|120-9|301)7/1/202445Thatisall,thankyou!
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 管理文书 > 施工组织


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!