文档章节

php正则表达式心得总结

爬墙
 爬墙
发布于 2016/12/25 22:59
字数 1589
阅读 41
收藏 0

一、php采用的是PCRE模式:

http://php.net/manual/zh/book.pcre.php
PCRE模式


二、常用函数

  1. preg_replace
    执行正则表达式替换
    http://php.net/manual/zh/function.preg-replace.php
preg_replace($pattern, $replacement, $string);
  1. preg_match
    执行一次正则表达式匹配
$subject = "abcdef";
$pattern = '/^def/';
preg_match($pattern, $subject, $matches, PREG_OFFSET_CAPTURE, 3);
print_r($matches);
  1. preg_match_all
    执行一个全局正则表达式匹配
    preg_match()返回 pattern 的匹配次数。 它的值将是0次(不匹配)或1次,因为preg_match()在第一次匹配后 将会停止搜索。preg_match_all()不同于此,它会一直搜索subject 直到到达结尾。 如果发生错误preg_match()返回 FALSE。

三、模式修饰符(匹配模式)

http://php.net/manual/zh/reference.pcre.pattern.modifiers.php

  • i:大小写不敏感
  • m:可跨行匹配,默认是不跨行匹配
  • s:点号元字符可匹配换行符,默认点元字符是不匹配换行符
  • U:这个修饰符逆转了量词的"贪婪"模式。 使量词默认为非贪婪的,通过量词后紧跟? 的方式可以使其成为贪婪的。这和 perl 是不兼容的。 它同样可以使用 模式内修饰符设置 (?U)进行设置, 或者在量词后以问号标记其非贪婪(比如.*?)
  • u:模式字符串被认为是utf-8的,php 4.3.5 开始检查模式的 utf-8 合法性
  • D:$元字符匹配结果中不包括换行符,默认模式是包括换行符的,设置成上面的m模式时会被忽略
  • x:不常用,模式中的没有经过转义的或不在字符类中的空白数据字符总会被忽略

四、还有一些函数

  1. preg_replace_callback 执行一个正则表达式搜索并且使用一个回调进行替换
  2. preg_split 正则分割字符串为数组

五、子组(子模式)

  1. 字符集匹配 如果是字符集是多个字符组成,也叫字组(子模式),比如匹配apple和orange任意一个:
this is a (apple|orange)
//如果要否定子模式,则需要使用断言:前断言?!和后断言?<!
this is a (?!apple|orange).*

会匹配:this a apple、this a orange、this a ,可以匹配空字符
如果不需要捕获括符内容的话,在前面加上 ?: 即可,如果需要再加上内部选项设置,在 ?:之间设置,一下写法作用是相同的

  1. 字组(子模式)命名 三种写法,后面两种需要版本>=php5.2.2支持:
(?P<name>pattern)
(?<name>pattern) 
(?'name'pattern)
  1. 多个子组可以共用一个后向引用数字
    有个这样的问题,当我们这样用的时候:
    (?:(Sat)ur|(Sun))day
    这里当后向引用 1 空时Sun 存储在后向引用 2 中. 当后向引用 2 不存在的时候 Sat 存储在后向引用 1中; 使用 (?| 修改模式来修复这个问题:
    (?|(Sat)ur|(Sun))day
    使用这个模式, Sun和Sat都会被存储到后向引用1中。

六、重复/量词

单字符量词

  • * 等价于 {0,}
  • + 等价于 {1,}
  • ? 等价于 {0,1}

特殊用法

  • 量词紧跟着一个 ?(问号) 标记,它就会成为懒惰(非贪婪)模式,如果在模式修饰符中设置了U 模式,量词后面加 ?(问号) 标记则成婪模式,就是和全局的匹配模式模式反着来。
  • 量词紧跟着一个 +(加号) 标记,它会吃掉整个字符串

七、后向引用

  1. 在大于等于php5.2.2版本中采用 \g{1} 写法可以更好的理解,序列\1, \g1,\g{1} 之间是同义词关系,这种用法可以消除使用反斜线紧跟数值描述反向引用时候产生的歧义

  2. \g 转义序列紧跟一个负数代表一个相对的后向引用。比如: (foo)(bar)\g{-1} 可以匹配字符串 ”foobarbar”, (foo)(bar)\g{1} 可以匹配 ”foobarfoo”。 这在长的模式中作为一个可选方案, 用来保持对之前一个特定子组的引用的子组序号的追踪。

  3. 后向引用也支持使用子组名称的语法方式描述, 比如 (?P=name) 或者 PHP 5.2.2 开始可以实用\k<name> 或 \k'name'。 另外在 PHP 5.2.4 中加入了对\k{name} 和 \g{name} 的支持。


八、断言

  1. 前瞻性断言:只对它前面的字符生效
  • 正面断言:以 (?= 开头
  • 消极断言:以 (?! 开头
  1. 后瞻性断言:只对它后面的字符生效
  • 正面断言:以 (?<= 开头
  • 消极断言:以 (?<! 开头

九、条件子组

可以使匹配器根据一个断言的结果, 或者之前的一个捕获子组是否匹配来条件式的匹配一个子组或者在两个可选子组中选择。 条件子组的两种语法如下:

(?(condition)yes-pattern)  
(?(condition)yes-pattern|no-pattern)

十、性能

Jeffrey Friedl 书(精通正则表达式)中包含了很多关于正则表达式性能的讨论。

  1. [aeiou] 这样的字符类会比可选路径 (a|e|i|o|u) 高效
  2. 模式匹配没有换行符的目标字符串,^.* 性能更佳
  3. (a+)b 比 (a+) 性能高,(a+)* 模式可以有 33 种方式匹配 ”aaaa”,它会尝试每种可能的变化,很消耗性能

十一、其他知识点

  1. 字符集匹配
    单个可选分支是这样写,比如匹配abc中任意一个:
[abc]

如果是字符集是多个字符组成,也叫字组(子模式),比如匹配apple和orange任意一个:

this is a (apple|orange|)

会匹配:this a apple、this a orange、this a ,可以匹配空字符
如果不需要捕获括符内容的话,在前面加上 ?: 即可,如果需要再加上内部选项设置,在 ?:之间设置,一下写法作用是相同的

(?i:saturday|sunday)
(?:(?i)saturday|sunday)
  1. 关于锚 ^ 元字符
    正常情况下^表示开头处,但是在字符集下,它代表反向(否定),比如下面表示不包含abc中任意一个字符
[^abc]
  1. 内部选项设置
    默认的模式修饰符是全局的,但有些场景需要使用局部修饰符(也就说说局部模式修饰符),比如某部分匹配可以不区分大小写(默认是严格大小写区分的),使用方法为:(?修饰符)
apple (?iand) orange

以上会匹配apple and orange、apple And orange等等

参考:http://louiszhai.github.io/2016/06/13/regexp/

© 著作权归作者所有

爬墙

爬墙

粉丝 14
博文 365
码字总数 88672
作品 0
美国
私信 提问
使用PHP做网页采集实例过程总结

最近有个任务是需要我检查一些网站,如果纯手工检查的话,感觉既费时又无聊。所以我就想用采集。思路其实很简单,先把网站的源码采集下来,然后用正则表达式去匹配符合的链接,最后把标题和网...

章郎虫
2013/12/27
0
0
python 爬虫抓取心得分享

/ author: insun title:python 爬虫抓取心得分享 blog:http://yxmhero1989.blog.163.com/blog/static/112157956201311821444664/ / 0x1.urllib.quote('要编码的字符串') 如果你要在url请求里......

quanwei9958
2014/07/25
0
0
linux grep正则学习(转载)

虽然正则表达式经常都在用,但是很少能够静下心来仔细的总结一下。最近看了一个台湾人的网站叫做鸟哥Linux私房菜,关于正则表达式的描述挺详细的。在此,我进行一下总结,如果想仔细的学习正...

开卷书生
2014/08/01
0
0
(转)Python中第三方模块的使用心得

前面已经说了,其实学习Python的过程,很多时候就是在学习如何使用第三方模块,完成自己需要的功能。 关于Python的第三方库类库,其实网上很多很多相关资料。 其中,官网的Python库:Python ...

Dyllian
2013/05/22
0
0
正则表达式中的子组模式

作者:西瓜玩偶(racnil070512 at hotmail dot com) 一、基础知识 在PCRE正则表达式中,我们可以利用圆括号定义一个子组,我们可以使用pregmatch函数(其他函数的信息请参考PHP官方API文档)...

snowing1990
2016/03/14
51
0

没有更多内容

加载失败,请刷新页面

加载更多

Java的线程同步和并发问题示例

并发问题 多线程是一个非常强大的工具,它使我们能够更好地利用系统的资源,但我们需要在读取和写入多个线程共享的数据时特别小心。 当多个线程尝试同时读取和写入共享数据时,会出现两种类型...

hiuh
43分钟前
1
0
Spring Boot 常用注解说明

实体类 @Entity (实体类注解) @Table(可指定表名) @Data(可缺省get/set) @Id (指定属性主键) @GeneratedValue(指定主键生成规则)

兜兜毛毛
今天
3
0
局域网能互相ping通,ubuntu虚拟机不能上外网

【问题】 桥接模式老是无法上网,查看本机IP发现被分配了一个私网地址,猜测应该是虚拟DHCP服务器没有打开,于是查看Ubuntu的网络配置: /etc/network/interfaces 发现没有dhcp配置的信息,只...

tahiti_aa
今天
2
0
以太坊助记词PHP开发包简介

以太坊助记词PHP开发包用来为PHP以太坊应用增加助记词和层级确定密钥支持能力。下载地址:以太坊助记词php开发包 。 1、开发包概述 以太坊助记词PHP开发包主要包括以下特性: 生成符合BIP39...

汇智网教程
昨天
2
0
系统监控-分布式调用链Skywalking

1. 为什么要使用分布式调用链技术? 随着公司业务的高速发展,公司服务之间的调用关系愈加复杂,如何理清并跟踪它们之间的调用关系就显的比较关键。线上每一个请求会经过多个业务系统,并产生...

秋日芒草
昨天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部