PCRE和正则表达式的问题
发布时间:2021-11-13 12:35:01 所属栏目:PHP教程 来源:互联网
导读:1.正则中所有的匹配模式,都应该理解为匹配了某字符或字符串后,紧跟着再匹配。这个概念很重要。 2.中括号首部使用脱字符时,表示的是紧跟着匹配不含给定字符的字符,而不是允许不匹配给定的字符。 它们大多数时候是等价的,但在匹配行尾时,意义不同,例如
1.正则中所有的匹配模式,都应该理解为"匹配了某字符或字符串后,紧跟着再匹配"。这个概念很重要。 2.中括号首部使用脱字符时,表示的是紧跟着匹配不含给定字符的字符,而不是允许不匹配给定的字符。 它们大多数时候是等价的,但在匹配行尾时,意义不同,例如:Aa[^bcd]$ 所匹配的行允许是Aaa$或Aax$,但不允许仅是Aa$。 这就是正则中"紧跟着匹配"的意思。 3.(.[0-9]+)? 可匹配小数点部分,不能写成 (.?[0-9]*) ,后者即使不能匹配小数点,也能匹配原本处于小数点后的数值 4.perl正则括号分组时,使用(?:替代左括号(,可以表示只分组不捕获。所谓的捕获表示的是可以反向引用或保存到正则外部的变量中 ([-+]?[0-9]+(.[0-9]+)?) *(cm|mm) :(cm|mm)将保存为$3 ([-+]?[0-9]+(?:.[0-9]+)?) *(cm|mm) : (cm|mm)将保存为$2 5.特殊锚定符,锚定所匹配的是位置,而非字符,行首^和行尾$同样如此。 注意某些程序对单词的理解和边界定义不一样,且有些程序并不完全支持下列所有的特殊元字符 例如gnu grep 2.6版本就不支持s和d,而gnu grep 2.20支持s但不支持d 'b':匹配单词边界处的空字符Match the empty string at the edge of a word. 'B':匹配单词边界处的非空字符Match the empty string provided it's not at the edge of a word. '<':匹配单词开头处的空字符Match the empty string at the beginning of word. '>':匹配单词结尾处的空字符Match the empty string at the end of word. 'w':匹配单词构成部分Match word constituent, it is a synonym for `[_[:alnum:]]'. 'W':匹配单词非构成部分Match non-word constituent, it is a synonym for `[^_[:alnum:]]'. 's':匹配空白字符Match whitespace, it is a synonym for `[[:space:]]'. 'S':匹配非空白字符Match non-whitespace, it is a synonym for `[^[:space:]]'. 'd':匹配数字it is a synonym for `[0-9]'. 'D':匹配非数字it is a synonym for `[^0-9]'. For example, 'bratb' matches the separate word 'rat', 'BratB' matches 'crate' but not 'furry rat'. 6.字符类,注意某些程序并不完全支持下列所有的字符类 '[:alnum:]' :same as '[0-9A-Za-z]'. '[:alpha:]' :'[:lower:]' and '[:upper:]', same as '[A-Za-z]'. '[:lower:]' : '[:upper:]' : '[:digit:]' :'0 1 2 3 4 5 6 7 8 9'. '[:xdigit:]' :Hex digits: `0 1 2 3 4 5 6 7 8 9 A B C D E F a b c d e f'. '[:blank:]' :space and tab. '[:space:]' :tab, newline, vertical tab, form feed, carriage return, and space. '[:punct:]' :Punctuation characters; this is '! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ ] ^ _ ` { | } ~'. '[:print:]' :'[:alnum:]', '[:punct:]', and space. '[:graph:]' :Graphical characters: '[:alnum:]' and '[:punct:]'. '[:cntrl:]' :Control characters. octal codes 000 through 037, and 177 (`DEL'). 7.同一个表达式中,被匹配过的字符无法被第二次匹配。因为正则的宗旨是:匹配了某字符或字符串后,紧跟着再匹配。 例如字符串"#c#",正则表达式"(#.)(.#)"无法匹配。 再例如字符串"#cc#",正则表达式"(.#)(.*)(.#)"能匹配成功,只不过第二个分组只能匹配空。 8."环视"锚定,即lookaround anchor。 以 (?= 替代左括号表示从左向右的顺序环视,例如(?=d)表示当前字符的右边是一个数字时就满足条件 以 (?<= 替代左括号表示从右向左的逆序环视,例如(?<=d)表示当前字符的左边是一个数字时就满足条件 正向环视:(?=...)和(?!...) 逆向环视:(?<=...)和(?<!...) 逆向环视的表达式必须只能表示固定长度的字符串,例如(?<=word)或(?<=word|word)可以,但(?<=word?)不可以,因为?匹配0或1长度,长度不定。 在PCRE中,可重写为(?<=word|words),但perl中不允许,因为perl严格要求长度必须固定。 9.关于"环视"锚定,最需要注意的一点是匹配的结果不占用任何字符,它仅仅只是锚定位置。 例如:your name is longshuai MA 和 your name is longfei MA 使用(?=longshuai)将能锚定第一个句子中单词"longshuai"前面的空字符,但它的匹配结果是"longshuai"前的空白字符, 所以(?=longshuai)long才能代表"long"这几个字符串 所以仅对于此处的两个句子,long(?=shuai)和(?=longshuai)long是等价的 10.贪婪匹配、惰性匹配和占有优先匹配 默认情况下,对于重复次数的表达式都是贪婪匹配,表示尽可能多的匹配。 有些高级正则引擎支持惰性匹配,表示尽可能少的匹配,只要能满足条件就立即停止。 * + ? {M,N} :都是贪婪匹配(lazy) *? +? ?? {M,N}? :都是惰性匹配(greedy) *+ ++ ?++ {M,N}+ :都是占有优先匹配(possessive) 占有优先和固化分组是相同的,只要占有了就不再交换,不允许进行回溯。示例见下面的(?>...)固化分组方式 11.匹配模式 (?i):不区分大小写,可使用(?-i)取消该模式。例如"(?i)abc(?-i)cdB"只对中间的abc进行不区分大小写的匹配 由于(?i)遇到闭括号就失效,可以将需要不区分大小写匹配的部分写入分组括号中,例如"((?i)abc)cdB",(?:(?i)abc)cdB=(?i:abc)cdB (?x):extend模式,将忽略多个连续空格和注释符到行尾的字符 (?m):(multiline)多行模式,改变^和$的匹配模式。默认模式下,它们匹配字符串首部和尾部。此模式下: ^将匹配字符串首部和换行符。若要仅匹配字符串首部,使用A。 $将匹配字符串尾部、换行符和换行符前的空字符。若要仅匹配字符串尾部和行尾,使用Z,若要仅匹配字符串尾部,使用z (?s):(singleline或dotall)单行模式,改变"."的匹配模式,默认模式下,点"."无法匹配换行符,dotall模式下可以 (?U):lazy匹配模式。默认是greedy匹配。 12.强制字面解释:Q...E。该序列将其中间的所有字符强制解释为字面符号,强制性极强。 但perl和pcre有所不同。perl中,该序列中间可引用变量进行变量替换,而pcre中变量符号也被当作普通字符。 13.普通分组和捕获 (),$1,$2,$3,$4...有些地方使用1,2,3,4,sed中使用&表示所有匹配,perl中则使用$& g1,g2,g3或g{1},g{2},g{3}。 其中$1,$2, ...用于正则外面,而"g1", "g2", ... 用于正则内部 14.命名分组和捕获 (?:...):非命名捕获,仅用于分组,不可用于引用,也称为非捕获型括号。例如"(1|one)(?:2|two)(3|three)",$1=(1|one),$2=(3|three) (?<NAME>...):命名捕获,分组捕获后还命名,就像变量赋值一样。可以使用k<NAME>或k'NAME'或g{NAME}的方法来引用 (?>...):固化分组。一匹配成功就永不交回内容(用回溯的想法理解很容易)。 例如"hello world"可以被"hel.* world"进行匹配,但不能被"hel(?>.*) world"匹配。 因为正常情况下,".*"匹配到所有内容,然后回溯释放一匹配内容直到空格" "字符。而固化分组后,已匹配的内容绝不交回,也就无法回溯。 (编辑:云计算网_泰州站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |