PHP正则表达式
平时用的不多,但是要用的时候总是要打开相关资料看一下,这次就对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
- preg_filter — 执行一个正则表达式搜索和替换
- preg_grep — 返回匹配模式的数组条目
- preg_last_error — 返回最后一个PCRE正则执行产生的错误代码
- preg_match_all — 执行一个全局正则表达式匹配
- preg_match — 执行一个正则表达式匹配
- preg_quote — 转义正则表达式字符
- preg_replace_callback — 执行一个正则表达式搜索并且使用一个回调进行替换
- preg_replace — 执行一个正则表达式的搜索和替换
- preg_split — 通过一个正则表达式分隔字符串
总结:
正则在很多时候可以快速方便的解决问题,其实所有正则能完成的工作都可以自己写算法来完成, 正则就是一套写好的字符串操作函数,
这些都是高级人员写好的,然后经过无数次的改革和优化,单个算法自然是达到了很高的效率,但是如果你的逻辑不是那么简单,要写一段很长很复杂的正则,那么这个效率就不能保证了,这种情况下如果能自己写一个针对性的函数或许效率会更高,说白了你使用正则就相当与在使用别人提供的API,理论来说这样的效率要低于自己写的较底层的函数,前提是你要有比较好的算法能力,so 善用正则
如果你已经决定要使用正则了,那么还有些技巧可以让你提高效率,比如 (a|b|c) 的效率 低于 [abc] ,前者使用了分支,而后者固定字符个数, 这些都要从算法说起,如果你懂得一些基本的算法, so 善用正则