首页 > 代码库 > php正则
php正则
$regex = ‘/^http:\/\/([\w.]+)\/([\w]+)\/([\w]+)\.html$/i‘ ; $str = ‘http://www.youku.com/show_page/id_ABCDEFG.html‘ ; $matches = array(); if (preg_match($regex, $str, $matches)){ var_dump($matches); } echo "\n" ; |
preg_match中的$matches[0]将包含与整个模式匹配的字符串。
使用"#"定界符的代码如下.这个时候对"/"就不转义!
$regex = ‘#^http://([\w.]+)/([\w]+)/([\w]+)\.html$#i‘ ; $str = ‘http://www.youku.com/show_page/id_ABCDEFG.html‘ ; $matches = array(); if (preg_match($regex, $str, $matches)){ var_dump($matches); } echo "\n" ; |
¤ 修饰符:用于改变正则表达式的行为。
我们看到的(‘/^http:\/\/([\w.]+)\/([\w]+)\/([\w]+)\.html/i‘)中的最后一个"i"就是修饰符,表示忽略大小写,还有一个我们经常用到的是"x"表示忽略空格。
贡献代码:
$regex = ‘/HELLO/‘ ; $str = ‘hello word‘ ; $matches = array (); if (preg_match( $regex , $str , $matches )){ echo ‘No i:Valid Successful!‘ , "\n" ; } if (preg_match( $regex . ‘i‘ , $str , $matches )){ echo ‘YES i:Valid Successful!‘ , "\n" ; } |
¤ 字符域:[\w]用方括号扩起来的部分就是字符域。
¤ 限定符:如[\w]{3,5}或者[\w]*或者[\w]+这些[\w]后面的符号都表示限定符。现介绍具体意义。
{3,5}表示3到5个字符。{3,}超过3个字符,{,5}最多5个,{3}三个字符。
* 表示0到多个
+ 表示1到多个。
¤ 脱字符号
^:
> 放在字符域(如:[^\w])中表示否定(不包括的意思)——“反向选择”
> 放在表达式之前,表示以当前这个字符开始。(/^n/i,表示以n开头)。
注意,我们经常管"\"叫"跳脱字符"。用于转义一些特殊符号,如".","/"
$regex = ‘/(?<=c)d(?=e)/‘ ; /* d 前面紧跟c, d 后面紧跟e*/ $str = ‘abcdefgk‘ ; $matches = array (); if (preg_match( $regex , $str , $matches )){ var_dump( $matches ); } echo "\n" ; |
否定意义:
$regex = ‘/(?<!c)d(?!e)/‘ ; /* d 前面不紧跟c, d 后面不紧跟e*/ $str = ‘abcdefgk‘ ; $matches = array (); if (preg_match( $regex , $str , $matches )){ var_dump( $matches ); } echo "\n" ; |
$regex = ‘/HE(?=L)LO/i‘ ; $str = ‘HELLO‘ ; $matches = array (); if (preg_match( $regex , $str , $matches )){ var_dump( $matches ); } echo "\n" ; |
打印不出结果!
$regex = ‘/HE(?=L)LLO/i‘ ; $str = ‘HELLO‘ ; $matches = array (); if (preg_match( $regex , $str , $matches )){ var_dump( $matches ); } echo "\n" ; |
能打印出结果!
说明:(?=L)意思是HE后面紧跟一个L字符。但是(?=L)本身不占字符,要与(L)区分,(L)本身占一个字符。
$regex = ‘/^(Chuanshanjia)[\w\s!]+\1$/‘ ; $str = ‘Chuanshanjia thank Chuanshanjia‘ ; $matches = array (); if (preg_match( $regex , $str , $matches )){ var_dump( $matches ); } echo "\n" ; |
$regex = ‘/(?P<author>chuanshanjia)[\s]Is[\s](?P=author)/i‘ ; $str = ‘author:chuanshanjia Is chuanshanjia‘ ; $matches = array (); if (preg_match( $regex , $str , $matches )){ var_dump( $matches ); } echo "\n" ; |
运行结果
惰性匹配(记住:会进行两部操作,请看下面的原理部分)
格式:限定符?
原理:"?":如果前面有限定符,会使用最小的数据。如“*”会取0个,而“+”会取1个,如过是{3,5}会取3个。
先看下面的两个代码:
代码1.
<?php $regex = ‘/heL*/i‘ ; $str = ‘heLLLLLLLLLLLLLLLL‘ ; if (preg_match( $regex , $str , $matches )){ var_dump( $matches ); } echo "\n" ; |
结果1.
代码2
<?php $regex = ‘/heL*?/i‘ ; $str = ‘heLLLLLLLLLLLLLLLL‘ ; if (preg_match( $regex , $str , $matches )){ var_dump( $matches ); } echo "\n" ; |
结果2
代码3,使用“+”
<?php $regex = ‘/heL+?/i‘ ; $str = ‘heLLLLLLLLLLLLLLLL‘ ; if (preg_match( $regex , $str , $matches )){ var_dump( $matches ); } echo "\n" ; |
结果3
代码4,使用{3,5}
<?php $regex = ‘/heL{3,10}?/i‘ ; $str = ‘heLLLLLLLLLLLLLLLL‘ ; if (preg_match( $regex , $str , $matches )){ var_dump( $matches ); } echo "\n" ; |
结果4
$regex = ‘/ ^host=(?<!\.)([\d.]+)(?!\.) (?#主机地址) \| ([\w!@#$%^&*()_+\-]+) (?#用户名) \| ([\w!@#$%^&*()_+\-]+) (?#密码) (?!\|)$/ix‘; $str = ‘host=192.168.10.221|root|123456‘ ; $matches = array (); if (preg_match( $regex , $str , $matches )){ var_dump( $matches ); } echo "\n" ; |
特殊字符 | 解释 |
* | 0到多次 |
+ | 1到多次还可以写成{1,} |
? | 0或1次 |
. | 匹配除换行符外的所有单个的字符 |
\w | [a-zA-Z0-9_] |
\s | 空白字符(空格,换行符,回车符)[\t\n\r] |
\d | [0-9] |
一.正则表达式 1.匹配符 1)头匹配符"^":如^0754,只匹配开头为0754的字符串 2)尾匹配符"$":如0754$,只匹配结尾为0754的字符串 3)全字匹配:将^和$结合,如^0754$,匹配0754字符串 2.转义字符 1)空字符: 换行\n 回车\r 制表符\t 2)其他字符: "$" \$ "^" \^ "+" \+ "/" \/ 3.通配符 1)*号:用来匹配前面一个字符是否在字符串中出现零次或多次. 例1:‘abc*‘,匹配含有ab的所有字符串。 2)+号:......................................一次或多次. 例2:‘abc+‘,匹配含有abc的所有字符串。 3)?号:......................................零次或一次. 例3:只匹配含有ab、abc结尾不再含c的字符串。如abca,aabc,aaab都可以,但abcc就不行。 4.关于转义字符\$与双、单引号(php4环境) 1)正则表达式本身就是一个字符串。 2)当引号中含有$时,用双、单引号定义就有区别,区别如下: (1)使用单引号定义时,解释器会把引号内所有字符(包括$在内)都原封不动的赋值给字符串变量。 (2)使用双引号定义时,解释器会把引号内"$"字符以及其后的合法字符(字母、数字、下划线)翻译成变量,直到遇到一个非法字符才认为变量名结束,该非法字符及其后面的字符都被视为一般字符赋给字符串变量,直到遇到下一个"$"为止。 (3)注意:单个$出现在双引号的尾部,并且其后面不再有任何字符的时候,解释器不会将其翻译成变量。也不需要加转义\,当然不提倡。 (4)如果待匹配的字符中本身就有$,就无法用双引号来定义这个正则表达式,原因是转义字符\$在单,双引号中表示的意义不同: <1>双引号中,\$和单个的$意义是一样的,都是代表尾匹配符,因此c\$$=c\$=c\$\$=c$=c\$\$;双引号中,\$在任何时刻都只代表一个字符"$",echo "c\$$"结果是c$$,并且\$和单个的$(单个的$是指该$无法和其后字符组成变量名)是完全等效的,都是尾匹配符,所以双引号中是无法写入作为非尾匹配字符的字符"$"的,也正是这个原因,大多数需要匹配$时定义正则表达式只能用‘‘。 <2>单引号中,\$的意义仅仅表示字符"$",尾匹配符是$,不管后面是否有合法变量名字符;单引号中,\$其实是两个字符,如不用于正则匹配将没有任何意义,echo ‘c\$$‘结果仍是c\$$。单作为正则表达式来使用,单引号中的\$表示的是特殊字符"$",而尾匹配符就是单独的$字符。 3)正则表达式的尾匹配符"$"和变量的定义符是相同的: 例1:定义正则表达式为^ab$:$pattern="^ab\$";转义字符\$在双引号中就表示字符$,结果是^ab$。 例2:如上题,使用$pattern="^ab$";显然是错误的,但是由于$在尾部,后面没有其他字符,所以依然适用。 例3:以字符组合c$结尾的正则表达式:$pattern=‘c\$$‘; 例4:如上题,$pattern="c\$$";正则表达式将\$视为尾匹配符,故只匹配以c结尾。 5."[]"方括号(字符簇)用法 1)[]匹配一个字符,在[]中使用^开头表示取非,即其后的字符全部是不匹配的。 例1:[a-zA-Z0-9]匹配所有大小写字母和数字。 例2:[\n\t\r\f]匹配所有空字符。 例3:[^A-Z]不匹配大写字母。 例4:^[^0-9]匹配不以数字开头的字符或字符串 2)特殊字符"."(句点)匹配除了"新行"之外的所有字符,模式^.abc$匹配任何以abc结尾的字符,但是不能匹配其本身。模式"."则可以匹配任何字符串,除了空字符串和只有一个"新行"字符的字符串。 例1:‘^.abc$‘;匹配所有尾部含有abc的字符串,不匹配小数(新行),当不匹配abc。 例2:‘.‘;匹配所有字符串,但不匹配空值。 例3:‘.abc‘;匹配所有含abc的字符串,小数等等都可以,前提是不以abc为首,不匹配abc。 例4:‘.abc$‘;匹配所有以abc结尾的字符串,任何小数等等都可以,不匹配abc。 3)php提供了内置通用字符簇: [[:alpha:]]任何字母 [[:digit:]]任何数字 [[:alnum:]]任何字母和数字 [[:space:]]任何空白字符 [[:upper:]]任何大写字母 [[:lower:]]任何小写字母 [[:punct:]]任何表点符号 [[:xdigit:]]任何十六进制数字 [[:cntrl:]]任何ASCII值小于32的字符 注意:以上字符簇有个特点,只要被匹配的字符或字符串中有此字符,即匹配正确,不管字符串是以什么方式组成的。 6."{}"大括号用法 1)方括号只能匹配一个字符,而匹配多个字符只能用{}实现:{}用来确定前面内容出现的次数。{n}表示出现n次;{m,n}表示出现m~n次,包括m和n次;{n,}表示出现n次或者n次以上。 例1:^a{10}$;匹配aaaaaaaaaa。 例2:[0-9]{1,}$;匹配所有>0的数。 2)"{}"与通配符之间的关系 ? 相当于 {0,1} 零次或一次 * ..... {0,} 零次或无数次 + ..... {1,} 一次或无数次 7."()"用法 圆括号"()"括住的pattern表示子模式,如$pattern=‘([1-9]{1}[0-9]{3})-([0-1]{1}[1-2]{1})-([0-3]{1}([0-9]|))‘;()扩住的就是一个个子模式,()相当于把他们独立起来,分别匹配而相互不干扰。 二.POSIX风格正则表达式函数 1.ereg ereg(pattern,string,[array $regs]); eregi(pattern,string,[array $regs]); ereg函数在string中找到满足pattern模式的文本,如果找到true,没找到false。如果有第三个参数$regs,那找到的文本将放在$regs[0]中,并且regs数组中将一次存放各个圆括号表达的子模式匹配的结果。$regs[1]中存放了第一个子模式所匹配的结果,$regs[2]中是第二个,顺序从左到右,依次类推。如果没有找到匹配的文本,$regs数组的值不会被改变。 注意:如果找到了匹配的文本,不管找到的子模式是多少个>9还是<9,ereg()只会改变$regs数组前10个元素的值。但是这不会影响函数对子模式组合的匹配结果。ereg总是先匹配完,如果没发现匹配的文本就false,发现了就true。如果有子模式,会逐步根据这些子模式重新在字符串中寻找匹配的文本,直到$regs数组被填满10个元素或者所有子模式被匹配完,如果子模式少于10则剩余的$regs将被赋空值。总之一句话,匹配归匹配,$regs归$regs,$regs只有10个值。 eregi()函数与ereg()基本用法相同,只是eregi对大小写不敏感。 2.ereg_replace和eregi_replace ereg_replace(pattern,string replacement,string) eregi_replace(pattern,string replacement,string) string字串中满足pattern的文本将被替换成replacement。如果string中有pattern匹配的文本,那么返回替换之后的值,如果没有,则返回原来的string值。 如果pattern中包含子模式,子模式可以有选择的被保留而不被替换。 例1:pattern中的第二个子模式不被替换,replacement可写成这样:replacement\\2。这样string中匹配的pattern的字符串将被替换为replacement+pattern2,pattern2表示匹配pattern的文本中又匹配pattern的第二个子模式的文本。如果使用"\\0"表示保留整个匹配文本。利用这个特性可以实现在特定的字符串之后插入文本的操作。 replacement必须是字符串类型变量,如果不是,替换时将强制转换成字符串类型。 3.split()函数和spliti()函数用法 split(pattern,string,[int limit]); spliti(pattern,string,[int limit]); split以正则表达式pattern定义的模式为分隔符将string分隔成几个部分。如果分隔成功,返回的值为各个分隔后部分组成的数组,失败则返回false。可选limit表示最大分割块数。如果limit为5,那么即使string有>5个的地方符合pattern,string也只被分割为5个部分,最后一个部分是string去掉前四个部分后剩下的部分。返回值中也只有5个元素。 三.perl风格正则表达式及相关函数 1.perl正则语法 perl分隔符,可使用"/","!"和"{}"。 例1:/^[^0-9]/ !^[0-9]! {^[0-9]}三个都一样。 在分隔符内部,分隔字符本身就是一个特殊敏感字符,要进行转义。如果用分隔符"/",正则中又用了表达字符的"/",则必须要用"\/"。如果混合用"/"和"!"就没问题。 例2:/\/\/$/ !//$! 两者也相同 例3:!^\!\![0-9]$! /^!![0-9]$/ 两者也相同 2.perl特殊意义字符 \a ASCII值为7的告警符 \b 词的边界 \A 和脱出符号("/")等价 \B 非词边界 \cn 控制字符 \d 单个数字 \D 单个非数字 \s 单个空白 \S 单个非空白 \w 单个的字母或下划线 \W 单个的非词字符(不是字母也不是下划线) \Z 从目标字串的尾部开始匹配 3.高级特性 1)或运算"|": 例如!^ex|em!匹配条件是ex或em开头的字符串,还可以写成!^e(x|m)!。 注意:()内的内容代表子模式\ 2)逻辑符号后面的模式选项 !正则表达式!逻辑选项 A:只匹配位于目标字串开头的字符。 E:该选项使转义字符$构成的正则表达式只匹配目标字符串的结尾字符。如果选择m选项,该选项就被忽略。 U:该选项禁止最大长度的搜索。一般情况下,搜索会尽量找最长的匹配字符串。例如模式/a+/在"caaaaab"字符串中的匹配结果是"aaaaa",但是使用该选项的模式/a+/U匹配的结果会是"a"。 S:对模式进行学习,提高查找速度。 i:该选项忽略大小写。 m:该选项将含有换行符的字符串视为多行而不是一行。这个时候"$","^"等字符会匹配每个换行符。 s:该选项使句点"."也匹配换行符。 x:该选项通知PHP解释器在分析的时候忽略正则表达式定义中的非转义空格符。这样可以在正则表达式中使用空格来增强其可读性,但这时在表达式中使用空格符必须使用转义字符。 3)扩展模式符号。 (?#comment) 添加注释comment,可以增强正则可读性。 (?=pattern) 指定在模式之后必须跟随值pattern。 (?!pattern) 指定在模式之后不能跟随值pattern。 (?n) 在模式内部而非结尾处定义模式选项n。 (?: ) 消耗字符,不捕获匹配结果。 例:echo ereg("?:^a$","a");//无任何输出。 4.per正则函数 1.preg_grep函数 preg_grep(pattern,array input); 输入数组input中寻找匹配模式pattern的字串,并将所有的匹配字符串返回。返回值就是所有匹配的字符串组成的数组。 2.preg_match函数 preg_match(pattern,string subject,[array matches]) 该函数在subject字符串中寻找匹配pattern的字符串。如果找到则返回一个非零值,否则返回零值。如果选用了可选项matches,那么匹配的字符串将被放到第一个元素的位置,可以用$matches[0]来读取,圆括号匹配的结果也按顺序放在这个数组中,第一个是$matches[1],第二个是$matches[2],依次类推。 3.preg_match_all函数 preg_match_all(pattern,subject,array matches,[int order]) 该函数在subject字符串中寻找匹配pattern的互不重叠的文本,找到了匹配的文本则返回匹配文本的个数,否则返回0。匹配文本被放在二维数组matches中,matches[0]中存放的是所有符合的字符串。各种嵌入的子模式匹配的结果依次放在数组matches[1]~[n]中。 order参数可选,可取的值为PREG_PATTERN_ORDER和PREG_SET_ORDER。 4.preg_replace函数 preg_replace(pattern,replacement,subject,[int limit]) 该函数将subject中符合pattern模式的部分替换成replacement,返回值类型和subject类型一样,如果有替换,则返回替换后的值,反之则返回原来的值。 参数可以是数组也可以是变量,有几种情况: <1>如果subject参数是数组类型。函数对每一个数组元素进行替换操作; <2>如果pattern是数组则函数根据每一个pattern中的类型进行替换; <3>如果pattern和replacement都是数组,则按两个数组中的元素对应完成替换; <4>如果replacement中的元素个数少于pattern中的元素个数。那么不够的部分将有空字符串来代替。 5.preg_split函数 preg_split(pattern,subject,[int limit][flages]) 该函数以pattern定义的模式为分隔符将subject字符串分隔为若干个部分,返回数组,其中存放被分隔后的字符串。limit可限制返回字符串的数目,如果设置为-1表示对返回的字符串数目不加任何限制。flags也是可选项,其有两个值:PREG_SPLIT_NO_EMPTY设定函数不返回空字符串,PERG_SPLIT_DELIM_CAPTURE,该选项设定pattern中的嵌入子模式也会被函数匹配。 |
php正则