PHP正则表达式

ccpp 10年前

平时用的不多,但是要用的时候总是要打开相关资料看一下,这次就对php的正则表达式做个总结,加深记忆并以便日后参阅,

其他语言不保证通用,比如javascript支持的正则就没有php那么多,

元字符:

 .         匹配除换行符以外的任意字符    

\w       匹配字母数字或下划线或汉字

\s        匹配任意空白符

\d        匹配数字

\b        匹配单词的开始或结束

^         匹配字符串的开始

$         匹配字符串的结束

-          表示范围

[]         匹配括号中的任意一个字符

量词:

*         重复0次或更多次

+         重复1次或更多次

?         重复0次或1次

{n}     重复n次

{n,}     重复n次或更多次

{n,m} 重复n到m次  

转义::    \        一般用来转义特殊字符,比如元字符    使用\*   就能匹配*了

反义:        一般情况,能不用反义的地方就不用 ,反义的范围太大了 会有很多你没想到的情况,容易出错

\W 匹配任意不是字符,数字,下划线,汉字的字符

\S 匹配任意不是空白的字符

\D 匹配任意非数字的字符

\B 匹配不是单词开头或结束的位置

[^x] 匹配除了x以外的任意字符

[^qwe] 匹配除了qwe这几个字符以外的字符

分支: |

(x|h|yo)at   匹配xat  hat   yoat 

分组:

(exp) 匹配exp,并不或文本到自动命名的组里

(?<name>exp) 匹配exp,并捕获文本到名称为name的组里   也可写成  (? 'name' exp)

(?:exp) 匹配exp,不捕获匹配的文本,也不分配组号

断言:   标准的说应该叫环视,断言是根据意思好记写的      (断言也是一种分组,所以也会被分配组号)   

(?=exp) 匹配exp前面的位置

(?<=exp) 匹配exp后面的位置

(?!exp) 匹配后面跟的不是exp的位置

(?<!exp) 匹配前面不是exp的位置

反向引用:   \1   --->引用组号为1的分组规则

如果前面使用了分组并分配了组号,在后面可以使用反向引用来使用前面某个组的规则,如果没有指定分组名,那么默认组号名从1开始自增

匹配模式:

忽略大小写模式    i

多行模式   m

对每一行进行一次匹配 ,返回多条匹配。  区别于跨行匹配,跨行是把多行视为一个整体匹配一次

点号通配模式  s

默认元字符点号是不能匹配换行符的,加上这个模式就可以匹配任意字符包括换行符了

懒惰模式  U

尽可能少的匹配     acbaab      a.*b    使用懒惰模式匹配  acb   否则匹配acbaab

结尾限制   D

abc$   匹配abc结尾的行,如果行末有换行符会忽略不计,如果使用D模式 ,那么只能以abc结尾,结尾处不能有换行符,否则不能匹配

支持utf8转义表达   U


php中有两套正则函数     PCRE   POSIX 

PHP推荐使用PCRE

  1. preg_filter — 执行一个正则表达式搜索和替换
  2. preg_grep — 返回匹配模式的数组条目
  3. preg_last_error — 返回最后一个PCRE正则执行产生的错误代码
  4. preg_match_all — 执行一个全局正则表达式匹配
  5. preg_match — 执行一个正则表达式匹配
  6. preg_quote — 转义正则表达式字符
  7. preg_replace_callback — 执行一个正则表达式搜索并且使用一个回调进行替换
  8. preg_replace — 执行一个正则表达式的搜索和替换
  9. preg_split — 通过一个正则表达式分隔字符串

总结:

正则在很多时候可以快速方便的解决问题,其实所有正则能完成的工作都可以自己写算法来完成,   正则就是一套写好的字符串操作函数,

这些都是高级人员写好的,然后经过无数次的改革和优化,单个算法自然是达到了很高的效率,但是如果你的逻辑不是那么简单,要写一段很长很复杂的正则,那么这个效率就不能保证了,这种情况下如果能自己写一个针对性的函数或许效率会更高,说白了你使用正则就相当与在使用别人提供的API,理论来说这样的效率要低于自己写的较底层的函数,前提是你要有比较好的算法能力,so    善用正则

如果你已经决定要使用正则了,那么还有些技巧可以让你提高效率,比如   (a|b|c)  的效率  低于  [abc] ,前者使用了分支,而后者固定字符个数, 这些都要从算法说起,如果你懂得一些基本的算法,  so  善用正则