竹磬网-邵珠庆の日记 生命只有一次,你可以用它来做些更多伟大的事情–Make the world a little better and easier


227月/119

PHP高级软件工程师课程体系

发布在 邵珠庆

 

课程介绍:

本课程共220课时,涉及到PHP开发的所有高级技术,通过进行大型Web项目的架构设计和开发。课程内容包括目前非常流行的像Ajax、 jQuery、PDO、Smarty模板、Soap、Memcached、MySQL数据库的高级应用,以及自己去编写框架进行应用,还有 ThinkPHP框架和一些比较常用的Zend产品和PHP6的最新特性。课程中的每个技术点的内容都非常全面,深度到位,课上实例不仅丰富而且实用。另 外,每个知识点都是以目前最新版本的技术设计,每半年一更新,并经过多家软件公司的技术专家参与修订,以达到真正实用的目的,能够与大型软件开发公司所需 要的开发技术相吻合。课程中的每个知识点都是程序开发人员必不可少的内容,都可以提高开发人员的开发效率,开发出安全、稳定的Web系统。

课程特点:

 

  • 1. 最主流的PHP和MySQL高级技术
  • 2. 将程序开发人员水平提高到一个新的高度
  • 3. 内容全面、案例丰富,采用目前最新的Web开发模式
  • 4. 与大型PHP开发型项目技术同步
  • 5. 课程中的技术点全部采用最新技术点讲解
  • 6. 课程中的两个项目全是采用现在最主流的MVC设计模式和面向对象技术开发,第一个项目使用自定义框架技术,第二个项目内使用国内最流行的ThinkPHP框架实现。
  • 7. 课程中涉及多种框架技术,使用开发人员不用再从底层一步步开发,就可以快速开发出安全稳定的项目,积累丰富的开发经验
  • 8. 以最短的时间,达到高级软件工程师水平
  • 9. 采用案例式教学,通过专家讲师的带领使学员可以具有独立开发大型网站的能力
  • 10. 课程的技术点完全采用编码规范,使学员熟练应用,提高编码效率

预期目标:

 

  • 1. 掌握所有Web开发的高级技能,积累大型项目的开发经验
  • 2. 通过这部分课程可以加强PHP高级部分学习,学员能熟练进行网站分析设计,数据库的结构设计,提高编程能力
  • 3. 符合企业需求的Web软件高级开发工程师
  • 4. 通过PDO的学习,可以提高数据库的处理效率,并可以以一种接口处理多种数据库,方便数据移植
  • 5. 通过Ajax、JQuery和Smarty的学习可以精通Web前台技术,编写出合格的网页界面
  • 6. 通过面向对象和MVC的学习可以将表现和业务分离
  • 7. 通过框架技术的学习,可以提高开发效率,掌握框架内容。
  • 8. 通过soap的学习,可以进行分布式开发
  • 9. 熟悉数据库服务器的维护、优化、安全设置,精通SQL语句编写
  • 10. 使用PHP技术可以独立完成建站工作,对现有的成熟产品进行二次开发,团队合作完成大型项目的设计与开发,以及产品的测试与维护

适合目标群体:

 

  • 1. 第一阶段学完,并完成项目开发的学员
  • 2. 有一些PHP基础,通过PHP开发过一些小项目
  • 3. 大学计算机系任课教师
  • 4. 运营和维护网站的管理员
  • 5. 从事多年像Asp.net或Java的程序员想转到PHP的程序员
  • 6. 从事过1年以内的PHP程序员,为提高自己的编程水平

常见的开发项目案例:

所有的个人和企业动态网站、淘宝网、京东商城、团购网、人人网、开心网、腾迅网、新浪网、CSDN技术社区、DeDeCMS系统、PHPWind论坛、微博,和所有现有产品的二次开发等

 

 

课程名 科目 内容 完成目标 课时(14)
PHP面向对象的程序设计
  • 面象对象的介绍
  • 类和对象之间的关系
  • 面向对象的程序设计

面向对象是PHP5中的新加功能,也是PHP以后编写代码的方式,本节掌握面向对象在行业中的应用,并了解一些基本的面向对象的声明语法。

1
  • 如何抽象一个类
  • 类的声明
  • 成员属性
  • 成员方法
  • 通过类实例化对象
  • 创建对象
  • 对象类型在内存中的分配
  • 对象中成员的访问
  • 特殊的对象引用“$this”
  • 构造方法与析构方法

本节掌握对象在程序中的应用,在内存中的分配形式,还要对象中的成员访问方式,并要掌握构造和析构以及关键字$this使用。

1
  • 封装性
  • 设置私有成员
  • 私有成员的访问
  • __set()、__get()、__isset()和__unset()
  • 四个方法

使用面向对象一定要使用他的三大特性,封装就是其中之一,这节掌握封装的意义以及封装的应用和各种与封装有关的魔术方法。

2
  • 继承性
  • 类继承的应用
  • 访问类型控制
  • 子类中重载父类的方法

继承性也是面向对象的三大特性之一,本节需要掌握继承的意义与应用,访问控制和重载的方式。

2
  • 常见的关键字和魔术方法
  • final关键字的应用
  • static和const关键字的使用
  • 克隆对象
  • 类中通用的方法__toString()
  • 通过__call()方法处理错误调用
  • 自动加载类
  • 对象串行化

在PHP的面向对象的程序设计中会用动一些常见的关键字和一些常用的魔术方法,在这一节中有许多都是常的,所以都需要全部掌握,并可以灵活运用。

1
  • 抽象类与接口和多态
  • 抽象方法和抽象类
  • 接口技术
  • 多态性的应用

这节主要了解抽象类和接口的作用,并掌握他们的声明与应用,重点掌握多态性的应用。

2
  • 与类和对象有关的系统函数
  • 与类有关的系统函数
  • 与对象有关的系统函数

PHP中提供的类和对象有关的函数不多,但比较常用。

1
  • 常用功能类的编写
  • 分页类
  • 验证码类
  • 图像处理类
  • 文件上传类
  • 数据验证类

通过这几个类的编写,不仅可以方便你在所有PHP项目中通用这些功能类,还可以对面向对象技术进行总结。

4

 

课程名 科目 内容 完成目标 课时(22)
PHP的mysqli模块扩展
  • MySQL存储过程
  • 存储过程及优点
  • MySQL实现存储过程
  • 存储过程集成在PHP应用中

存储过程是一种存储在书库中的程序,本节需要掌握一个存储过程包括名子,参数列表,以及包括很多SQL语句的SQL语句集,以及对局部变量,异常处理,循环控制和IF条件名的语法定义。

2
  • MySQL触发器
  • 触发器介绍
  • MySQL对触发器的支持

本节需要掌握触发器的应用,使用如果在PHP中使用触发器。

2
  • 数据库视图
  • 视图的应用介绍
  • MySQL对视图的支持
  • 将视图集成到PHP应用程序中

本节中介绍视图的应用,需要掌握MySQL对视图的支技和如果将视图整合到PHP应用程序中。

1
  • 实用数据库查询及优化
  • SQL语句查询优化
  • 排序输出
  • 创建分页输出
  • 列出页码
  • 子查询

本节主要内容是介绍一些在PHP项目中常用到的SQL语句的编写,掌握一些SQL语句的使用和优化的技巧。

2
  • 索引和搜索
  • 数据库索引介绍
  • 数据库应用
  • 基于表单的搜索

本节需要掌握如何为一个数据表创建索引,提高数据库的搜索过程,和掌握事务处理的原理和操作方法,并将其和PHP程序结合使用。

1
  • 事务处理
  • 什么是事务
  • MySQL的事务功能
  • 用PHP构建事务应用程序
  • 编写数据库操作类
  • 编写数据库操作类
  • 启用mysqli扩展模块
  • 使用mysqli的概述及安装

PHP的mysqli模块是对mysql模块的改进,使用PHP处理数据库效率有所提高,也使用的面向对象的处理方式,本节需要掌握mysqli安装、连接,以及和连接相关的mysqli类中成员的应用。

1
  • 使用mysqli类
  • 连接MySQL服务器
  • 处理连接错误报告
  • 关闭与MySQL服务器连接
  • 执行SQL命令
  • 使用mysqli_result类
  • 创建结果集对象
  • 回收查询内存
  • 从结果集中解析数据
  • 从结果集中获取数据列的信息
  • 一次执行多条SQL命令

本节主要需要掌握mysqli结果集对象的处理方法和属性,完成对数据中查询到的结果进行处理。

1
  • 使用mysqli_stmt类
  • 获取预处理语句对象
  • 绑定参数
  • 执行准备好的语句
  • 回收资源
  • 简单的示例分析
  • 使用预处理语句处理SELECT查询

本节需要掌握预处理对象的应用,以及如果使用问号参数,绑定参数,执行准备好的语句,和处理SELECT查询等。并可以通过mysqli完成事务处理的操作。

2
  • MySQLi数据库事务
  • 使用MySQLi进行事务处理
  • 构建事务应用程序
数据库抽象层PDO
  • PDO所支持的数据库
  • PDO的应用及所支持的数据库

本节要掌握PDO的应用原理和驱动设置,以及PDO的安装方法,并可以以多种方式创建PDO对象,和面要了解PDO对象中的成员。

1
  • PDO的安装
  • PDO的安装方法
  • 创建PDO对象
  • 以多种方式调用构造方法
  • PDO对象中的成员方法
  • 使用PDO对象
  • 调整PDO的行为属性
  • PDO处理PHP程序和数据库之间的数据类型转换
  • PDO的错误处理模式
  • 使用PDO执行SQL语句

本节需要掌握PHP中的各种属性的应用、设置和读取,以及PDO的错误处理模式,还需要了解通过PDO执行SQL语句。

1
  • PDO对预处理语句的支持
  • 了解PDOStatement对象
  • 准备语句
  • 绑定参数
  • 执行准备好的查询
  • 获取数据
  • 大数据对象的存取

PDO的预处理对象,可以完成PHP程序和数据库之间的各种操作。本节需要掌握如果使用PDO准备预处理语句,和绑定参数、执行准备好的语句,获取数据和大数据对象的存取,并可以使用PDO完成事务处理操作。

2
  • PDO的事务处理
  • PDO的事务处理方式
Memcached应用
  • 设计无限分类
  • Memcached的工作原理
  • 在Web开发中使用Memcached
  • 安装和应用Memcache服务器
  • Memcache服务器的管理
  • 操作和遍历Memcache内容
  • 在PHP中使用Memcached
  • Memcached安全设置

memcached是一个高性能的分布 式的内存对象缓存系统,通过在内存里维护一个统一的巨大的hash表,它能够用来存储各种格式的数据,包括图像、视频、文件以及数据库检索的结果等。这个 缓存项目来构建自己大负载的网站,来分担数据库的压力。需要掌握Memcache全部细节。

2
session的高级
  • 设计无限分类
  • 将session信息写入远程文件中
  • 将session信息写入到数据库中
  • 将session信息写入到Memcached中
  • 统计在线用户列表

Session的信息除了可以写入到默认的文件中,也可以自己指定远程文件,以及写入到数据表中,还可以写入memcached来管理用户的信息,这是最优的一种方式,通过这种用法不仅可以提高管理用户信息的效率,还能方便完成在线用户的统计,掌握会话控制的全部技能。

3
项目设计
  • 设计无限分类
  • 设计无限分类
  • 添加分类
  • 修改分类
  • 删除分类
  • 使用分类

通过该项项目的开发,不仅可以完成无限分类的设计,还可以帮助掌握数据库的应用,以及PHP中处理数据库的方式。

3

 

课程名 科目 内容 完成目标 课时(40)
页面特效开发脚本
  • JavaScript
  • JavaScript应用概述
  • JavaScript脚本中变量与运算符
  • JavaScript流程控制和函数
  • JavaScript中数组和对象的创建及应用

可以完成JavaScript的所有语法的学习,以及和HTML和CSS联合使用,并可以编写一些页面中常见的脚本程序。

8
  • DOM编程
  • DOM及DHTML的应用介绍
  • 各种事件及事件处理程序的应用
  • 窗口window对象的属性和方法
  • 文档document对象的应用
  • 其location、body、form、screen等对象的使用

学会页面中DOM的灵活应用、事件处理,还有各种DOM对象的属性和方法,以及网页中所有特效的编写。

12
  • XML
  • XML介绍
  • DTD介绍
  • 名字空间

XML技术也是在Web开发中常见的应用形式, 本节掌握XML文件的编写和注意事项,以及DTD的应用与语法格式。

2
  • XML DOM
  • DOM节点访问
  • DOM节点信息
  • DOM节点列表
  • DOM解析
  • DOM遍历节点

本节掌握通过JavaScript中的XML DOM去实现XML节点数的遍历、添加、删除和悠改,并处理各种浏览器之间的差异。

2
  • Ajax的应用
  • Ajax概述
  • Ajax定义
  • 使用Ajax创建Ajax的引擎
  • Ajax Web应用模式(异步)
  • Ajax 开发中的应用
  • 编写和应用自定义的Ajax类
  • 使用Ajax完成XML的操作
  • 在Ajax应用json技术

这节要了解异步传递数据的方式,并掌握创建Ajax对象和应用Ajax对象中的属性和方法。通过完成编写Ajax对象的应用,简化Ajax的应用。

4
Ajax与JQuery框架应用
  • JQuery的使用
  • JQuery的概述
  • JQuery的核心方法
  • JQuery的选择器
  • JQuery的属性
  • JQuery的筛选和文档处理
  • JQuery的CSS应用

本节需要掌握在HTML文件中添加JQuery的应用,可以使用JQuery中的核心方法,以及常用选择器的使用,和一些常用的JQuery方法。

2
  • JQuery的Ajax应用
  • JQuery的事件
  • JQuery的效果
  • 使用JQuery中的Ajax应用

Ajax是JQuery重点实现的技术,掌握JQuery中的几种实现方法。

2
  • JQuery的实例开发
  • 使用JQuery开发可以编辑的表格
  • 使用JQuery开发页面选择卡实例
  • JQuery的导航菜单的制做

使用JQuery实现一些常见的页面实例,进面巩固JQuery的学习。

4
PHP与XML
  • PHP处理XML
  • XML与PHP的应用
  • 以DOM方式解析XML
  • 以sax方式解析XML
  • RSS处理

本节需要掌握PHP处理XML的方式,包括DOM和SAX两种方式。

2
  • Web Service应用
  • Web Service介绍
  • SOAP介绍
  • SOAP的应用

Web Service是Web开发中常见的技术,这节需要掌握SOAP的应用。

2

 

课程名 科目 详细内容 完成目标 课时(34)
PHP的模板技术Smarty
  • 什么是模板引擎
  • 模板引擎的应用

了解模板技术在PHP开发中的应用,并通过编写简单的模板引擎,掌握模板引擎的工作原理。

1
  • 编写自己的模板引擎
  • 创建自己的模板引擎类
  • 使用自已的模板引擎
  • 自定义模板的使用示例分析
  • 选择Smarty模板引擎
  • Smarty模板引擎应用

本节需要掌握Smarty的安装和安使用化Smarty对象的一些些节,并通过一个简单的示例来了解Smarty工作原理,以及在应用程序中使用Smarty模板技术的步骤。

2
  • 安装Smarty及初使化配置
  • 安装Smarty初使化Smarty类库的默认设置
  • 第一个Smarty的简单示例
  • Smarty在应用程序逻辑层
  • Smarty在应用程序逻辑层的使用步骤
  • Smarty模板中的程序逻辑
  • 模板中的注释
  • 模板中变量的声明
  • 在模板中输出从PHP分配的变量
  • 模板中变量的数学计算
  • 在模板中使用{$smarty}保留变量
  • 变量调解器
  • 模板的控制结构
  • 在模板中包含子模板

本节需要掌握Smarty的基本语法,包括在模板中的注释,变量的声明,以在PHP中向模板中分配变量,还有保留变理和变量调解器、控制结构和子模板的应用。

2
  • 为Smarty模板创建配置文件
  • 后台状态栏
  • 配置文件语法格式
  • 加载配置文件
  • 引用配置文件中的变量

这节需要掌握为什么要使用配置文件,和配置文件的使用方法。

1
  • Smarty处理页面缓存
  • 在Smarty中控制缓存
  • 每个页面多个缓存
  • 为缓存实例消除处理开销
  • 清除缓存
  • 关闭局部缓存

缓存是模板技术中重点需要实现的,本节需要掌握模板的开启选项,使用多个缓存,以及消除处理开销和清除关闭局部缓存。

2
PHP设计模式
  • MVC模式
  • MVC模式介绍

本节需要掌握MVC的设计模式,包括视图、控制器、模型的应用。

4
创建自己的PHP框架
  • 自定义框架掌握PHP框架内幕
  • 了解主入口文件
  • 写URL路由
  • 自己定义全局控制器类
  • 自己定义全局业务模型类
  • 优化自己的框架
  • 使用自定义PHP框架创建应用

框架是开发项目的半成品,可以将项目开发的时间提高50%,通过自己定义的框架技术不仅可以将所学的知识点全部串在一起应用,还可以掌握框架内幕,对以后的学习和工作大有帮助,需要掌握框架开发的每个细节。

10
PHP中应用框架技术
  • ThinkPHP配置
  • 目录结构
  • MVC分层

本节需要掌握ThinkPHP的工作方式和ThinkPHP的目录结构。

2
  • 控制器
  • 商品的添加
  • 模块和操作
  • URL优化
  • 模块的高级操作
  • 页面跳转 重定向

本节需要掌握控制器的编写结构和访问方式,并掌握ThinkPHP内置控制中的一些常用方法。

2
  • 模型
  • 页面的布局
  • 模型和操作
  • CURD操作
  • 数据验证
  • 查询语言
  • 高级模型
  • 视图模型
  • 关联模型

本节需要掌握模型的操作,包括ThinkPHP中常用的模型功能。

2
  • 视图
  • 模板与操作
  • ThinkPHP模板技术

重点掌握ThinkPHP的模板应用以及一些模板的相关操作。

2
  • 特殊处理
  • 错误和日志
  • 调试
  • 缓存
  • 安全

掌握一些ThinkPHP的特殊处理,包括错误和日志、调试、缓存以及安全方面的处理。

1
  • 功能类库
  • 数据分页
  • 文件上传
  • 验证码
  • 图像处理

掌握ThinkPHP中内置的常用功能类库,也要掌握自己编写类型对ThinkPHP时进行扩展。

1
  • Rbac权限管理
  • Rbac权限管理详解

掌握ThinkPHP中处理用户权限

1
  • 第三方软件和第三方类库
  • FCK应用
  • JQuery结合

本节需要掌握ThinkPHP与第三方常用的软件库和类库的结合应用。

1
PHP6的新特性
  • PHP6中的新特性
  • PHP6.0更加好的Unicode支持
  • NameSpace:名字空间,将更好的避免在函数及类之间的变量名冲突
  • PHP6.0令人激动的Web2.0特性
  • PHP6中的XML与SOAP

介绍了PHP6中的新特性和已更改的特性。其中最主要的特性就是对Unicode的支持。删除了一些配置选项,改进了扩展支持和OO函数。PHPV5.3支持PHPV6的50%的特性。

2
  • PHP6的扩展
  • 删除了几个函数
  • 默认情况下不启用
  • 一些常用的改进
  • 一些有用的扩展
Zend的产品
  • Zend Guard
  • Zend Guard安装
  • Zend Guard使用加密PHP代码

Zend公司的核心产品应该是PHP语言。其实我们把PHP理解为一个Web引擎或开发平台可能也没错。Zend公司依托其优秀的、开源的PHP语言在程序员中创下了良好的口碑,并围绕PHP语言开发了一系列的支持产品,形成了一条从Web项目/产品开发到部署的生产线。

18
  • Zend Core
  • Zend Core的安装
  • Zend Cord的环境使用
  • Zend Studio
  • Zend Studio安装
  • Zend Studio工具的使用
  • Zend Framework
  • ZF访问方式
  • ZF环境配置
  • ZF组织页面
  • ZF安排控制器和action
  • ZF启用Zend_Layout
  • ZF初始化数据库连接与操作
  • 使用ZF开发一个文章管理模块

 

科目 内容 完成目标 课时(40)
第二个项目基于自定义PHP框架
  • 内容管理系统(CMS)

以组为单位任选一个项目,完成项目的分析、设计、编码、整合与测试,并可以正常运行,消除BUG.符合代码的编码规范和Web开发规范,并要基于MVC模式和面向对象思想,并用到前面课程所学到的全部知识点完成项目。

40
  • 在线考试系统
  • 办工自动化系统(OA)

 

科目 内容 完成目标 课时(48)
基于ThinkPHP框架
  • 基于ThinkPHP的电子商务系统

以组为单位任选一个项目,基于ThinkPHP的框架技术实现。

48
  • 基于ThinkPHP的论坛BBS系统
  • 基于ThinkPHP开发物流管理系统

 

16月/070

正则表达式高级技巧背后的关键概念

发布在 邵珠庆

英文原文来自Smashing Magazine 。由笨活儿 翻译。转载请注明出处。

正则表达式(Regular Expression, abbr. regex ) 功能强大,能够用于在一大串字符里找到所需信息。它利用约定俗成的字符结构表达式来发生作用。不幸的是,简单的正则表达式对于一些高级运用,功能远远不够。若要进行筛选的结构比较复杂,你可能就需要用到高级正则表达式

本文为您介绍正则表达式的高级技巧 。我们筛选出了八个常用的概念,并配上实例解析,每个例子都是满足某种复杂要求的简单写法。如果你对正则的基本概念尚缺乏了解,请先阅读这篇文章 ,或者这个教程 ,或者维基条目

这里的正则语法适用于PHP,与Perl 兼容。

 

1. 贪婪/懒惰

Greed

所有能多次限定的正则运算符都是贪婪的。他们尽可能多 地匹配目标字符串,也就是说匹配结果会尽可能地长 。不幸的是,这种做法并不总是我们想要的。因此,我们添加“懒惰”限定符来解决问题。在各个贪婪运算符后添加“?”能让表达式只匹配尽可能短 的长度。另外,修改器“U”也能惰化能多次限定的运算符。理解贪婪与懒惰的区别是运用高级正则表达式的基础。

贪婪操作符

操作符 * 匹配之前的表达式零次或零次以上。它是一个贪婪操作符。请看下面的例子:

1 preg_match( '/<h1>.*< //h1>/' , '</h1><h1>这是一个标题。</h1>
2 <h1>这是另一个。</h1>', $matches );

句点(.)能代表除换行符外的任意字符。上面的正则表达式匹配 h1 标签以及标签内的所有内容。它用句点(.)和星号(*)来匹配标签内的所有内容。匹配结果如下:

1 <H1>这是一个标题。</H1>
2 <H1>这是另一个。</H1>

整个字串都被返回。* 操作符会连续匹配所有内容—— 甚至包括中间的 h1 闭合标签。因为它是贪婪的,匹配整个字串是符合其利益最大化原则。

懒惰操作符

把上面的式子稍作修改,加上一个问号(?),能让表达式变懒惰:

1 /<h1>.*?< //h1>/</h1>

这样它会觉得,只需匹配到第一个 h1 结尾标签就完成任务了。

另一个有着类似属性的贪婪操作符是 {n,} 。它代表之前的匹配模式重复n次或n次以上,如果没有加上问号,它会寻找尽可能多的重复次数,加上的话,则会尽可能少重复(当然也就是“重复n次”最少)。

1 # 建立字串
2 $str = 'hihihi oops hi' ;
3 # 使用贪婪的{n,}操作符进行匹配
4 preg_match( '/(hi){2,}/' , $str , $matches );  # matches[0] 将是 'hihihi'
5 # 使用堕化了的 {n,}? 操作符匹配
6 preg_match( '/(hi){2,}?/' , $str , $matches );  # matches[0] 将是 'hihi'

2. 回返引用(Back referencing)

Back Referencing

有什么用?

回返引用(Back referencing) 一般被翻译成“反向引用”、“后向引用”、“向后引用”,个人觉得“回返引用”更为贴切[笨活儿 ]。它是在正则表达式内部引用之前捕获到的内容 的方法。例如,下面这个简单例子的目的是匹配出引号内部的内容:

01 # 建立匹配数组
02 $matches = array ();
03  
04 # 建立字串
05 $str = "/"This is a 'string'/"" ;
06  
07 # 用正则表达式捕捉内容
08 preg_match( "/(/"|').*?(/"|')/" , $str , $matches );
09  
10 # 输出整个匹配字串
11 echo   $matches [0];

它会输出:

1 "This is a'

显然,这并不是我们想要的内容。

这个表达式从开头的双引号开始匹配,遭遇单引号之后就错误地结束了匹配。这是因为表达式里说:("|') ,也就是双引号(" )和单引号(')均可。要修正这个问题,你可以用到回返引用。表达式/1,/2,…,/9 是对前面已捕获到的各个子内容的编组序号,能作为对这些编组的“指针”而被引用。在此例中,第一个被匹配的引号就由1 代表。

如何运用?

将上面的例子中,后面的闭合引号替换为1:

1 preg_match( '/("|/').*?/1/' , $str , $matches );

这会正确地返回字串:

1 "This is a 'string'"

译注思考题:

如果是中文引号,前引号和后引号不是同一个字符,怎么办?

还记得PHP函数 preg_replace 吗?其中也有回返引用。只不过我们没有用 /1 … /9,而是用了 $1 … $9 … $n (此处任意数目均可)作为回返指针。例如,如果你想把所有的段落标签

都替换成文本:

1 $text = preg_replace( '/<p>(.*?)< //p>/' ,
2 '&lt;p&gt;$1&lt;/p&gt;' , $html );

参数$1是一个回返引用,代表段落标签

内部的文字,并插入到替换后的文本里。这种简便易用的表达式写法为我们提供了一个获取已匹配文字的简单方法,甚至在替换文本时也能使用。

3. 已命名捕获组(Named Groups)

当在一个表达式内多次用到回调引用时,很容易就把事情搞混淆,要弄清那些数字(/1 … /9)都代表哪一个子内容是件很麻烦的事。回调引用的一个替代方法是使用带名字的捕获组(下文简称“有名组”)。有名组使用(?Ppattern) 来设定,name代表组名,pattern是配合该有名组的正则结构。请看下面的例子:

1 /(?P<quote>"|').*?(?P=quote)/

上式中,quote就是组名,"|' 是改组匹配内容的正则。后面的(?P=quote)是在调用组名为quote的有名组。这个式子的效果和上面的回调引用实例一样,只不过是用了有名组来实现。是不是更加易读易懂了?

有名组也能用于处理已匹配内容之数组的内部数据。赋予特定正则的组名也能作为所匹配到的内容在数组内部的索引词。

1 preg_match( '/(?P<quote>"|/')/' , " 'String' ", $matches );
2  
3 # 下面的语句输出“'”(不包括双引号)
4 echo $matches [1];
5  
6 # 使用组名调用,也会输出“'”
7 echo $matches [ 'quote' ];

所以,有名组并不只是让写代码更容易,它也能用于组织代码。

4. 字词边界(Word Boundaries)

Word Boundaries

字词边界 是字串里的字词字符(包括字母、数字和下划线,自然也包括汉字)和非字词字符之间的位置。其特殊之处就在于,它并不匹配某个实在的字符。它的长度是 。 /b 匹配所有字词边界。

不幸的是,字词边界一般都被忽视掉了,大部分人都没有在意他的现实意义。 例如,如果你想要匹配单词“import”:

1 /import/

注意了!正则表达式有时候很调皮的。下面的字串也能和上面的式子匹配成功:

1 important

你或许觉得,只要在import前后加上空格,不就可以匹配这个独立的单词了:

1 / import /

那如果遇上这种情况呢:

1 The trader voted for the import

当 import 这个词在字串开头或者结尾时,修改后的表达式仍然不能用。因此,考虑各种情况是必须的:

1 /(^import | import | import$)/i

别慌,还没完呢。如果遇到标点符号了呢?就为了满足这一个单词的匹配,你的正则可能就需要这样写:

1 /(^import(:|;|,)? | import(:|;|,)? | import(/.|/?|!)?$)/i

对于只匹配一个单词来说,这样做实在是有点大动干戈了。正因如此,字词边界才显得意义重大。要适应上述要求,以及很多其他情况变种 ,有了字符边界,我们所需写的代码只是:

1 //bimport/b/

上面所有情况都得到了解决。/ b 的灵活性就在于,它是一个没有长度的匹配。它只匹配两个实际字符之间想象出的位置。它检查两个相邻字符是否是一个为单字,另一个为非单字。情况符合,就返回匹配。如果遇到了单词的开头或结尾, /b 会把它当成是非单词字符对待。由于import里面的 i 仍然被看成是单词字符,import 就被匹配出来了。

注意,与/b 相对,我们还有/B ,此操作符匹配两个单字或者两个非单字之间的位置。因此,如果你想匹配在某个单词内部的‘hi’,可以使用:

1 /Bhi/B

“this”、“hight”,都会返回匹配,而“hi there”则不会返回匹配。

5. 最小组团(Atomic Groups)

Advanced Operators

最小组团 是无捕捉的特殊正则表达式分组。通常用来提高正则表达式的效能,也能用于消除特定匹配。一个最小组团可以用(?>pattern) 来定义,其中pattern是匹配式。

1 /(?>his|this)/

当正则引擎针对最小组团进行匹配时,它会跳过组团内标记的回溯位置。以单词“smashing”为例,当用上面的正则表达式匹配时,正则引擎会先尝试在“smashing”里寻找“his”。显然,找不到任何匹配。此时,最小组团就发挥作用了:正则引擎会放弃所有回溯位置。也就是说,它不会尝试再从“smashing”里查找“this”。为什么要这样设置?因为“his”都没有返回匹配结果,包含有“his”的“this”当然就更匹配不了了!

上面的例子并没有什么实用性,我们用/t?his?/ 也能达到效果。再看看下面的例子:

1 //b(engineer|engrave| end )/b/

如果把“engineering”拿去匹配,正则引擎会先匹配到“engineer”,但接下来就遇到了字词边界,/b ,所以匹配不成功。然后,正则引擎又会尝试在字串里寻找下一个匹配内容:engrave。匹配到eng的时候,后面的又对不上了,匹配失败。最后,尝试“end”,结果同样是失败。仔细观察,你会发现,一旦engineer匹配失败,并且都抵达了字词边界,“engrave”和“end”这两个词就已经不可能匹配成功了。这两个词都比engineer短小,正则引擎不应该再多做无谓的尝试。

1 //b(?>engineer|engrave| end )/b/

上面的替代写法更能节省正则引擎的匹配时间,提高代码的工作效率。

6. 递归(Recursion)

Recursion

递归(Recursion) 用于匹配嵌套结构,例如括弧嵌套, (this (that)),HTML标签嵌套

。我们使用(?R) 来代表递归过程中的子模式。下面是一个匹配嵌套括弧的例子:

1 //(((?>[^()]+)|(?R))*/)/

最外层使用了反义符的括号“( ”匹配嵌套结构的开端。然后是一个多选项操作符( * | * ) ,可能匹配除括号外的所有字符 “(?>[^()]+)”,也可能是通过子模式“(?R) ”来再次匹配整个表达式。请注意,这个操作符会尽量多地匹配所有嵌套。

递归的另一个实例如下:

1 /< ([/w]+).*?>((?>[^<>]+)|((?R)))*< ///1>/

以上表达式综合运用了字符分组,贪婪操作符、回溯,以及最小化组团来匹配嵌套标签。第一个括弧内分组([/w]+) 匹配出标签名,用于接下来的应用。若找到这尖括号样式的标签,则尝试寻找标签内容的剩余部分。下一个括弧括起来的子表达式和上一个实例非常相似:要么匹配不包括尖括号的所有字符 ?>[^<>]+ ,要么递归匹配整个表达式(?R) 。表达式最后的< //1> 代表闭合标签。

7. 回调(Callbacks)

Callbacks

匹配结果中的特定内容有时可能会需要某种特别的修改。要应用多重而复杂的修改,正则表达式的回调 就有了用武之地。回调是用于函数preg_replace_callback 中的动态修改字串的方式。你可以为preg_replace_callback 指定某个函数为参数,此函数能接收匹配结果数组为参数,并将数组修改后返回,作为替换的结果。

例如,我们想将某字串中的字母全部转变成大写。十分不巧,PHP没有直接转化字母大小写的正则操作符。要完成这项任务,就可以用到正则回调。首先,表达式要匹配出所有需要被大写的字母:

1 //b/w/

上式同时使用了字词边界和字符类。光有这个式子还不够,我们还需要一个回调函数:

1 function upper_case( $matches ) {
2 return strtoupper ( $matches [0] );
3 }

函数upper_case 接收匹配结果数组,并将整个匹配结果转化成大写。 在此例中,$matches[0] 代表需要被大写化的字母。然后,我们再利用preg_replace_callback 实现回调:

1 preg_replace_callback( '//b/w/' , 'upper_case' , $str );

一个简单的回调即有这般强大的力量。

8. 注释(Commenting)

Commenting

注释 不用来匹配字串,但确实是正则表达式中最重要的部分。当正则越写越深入,越写越复杂,要推译出究竟什么东西被匹配就会变得越来越困难。在正则表达式中间加上注释,是最小化将来的迷糊和困惑的最佳方式。

要在正则表达式内部加上注释,使用(?#comment) 格式。把“comment”替换成你的注释语句:

1 /(?#数字)/d/

如果你打算把代码公之于众,为正则表达式加上注释就显得尤为重要。这样别人才能更容易看懂和修改你的代码。和其他场合的注释一样,这样做也能为你重访自己以前写的程序时提供方便。

考虑使用“x”或“(?x)”修改器来格式化注释。这个修改器让正则引擎忽略表达式参数之间的空格。“有用的”空格仍然能够通过[ ] 或/s ,或者/ (反义符加空格)来匹配。

1 /
2 /d    #digit
3 [ ]   #space
4 /w+   #word
5 /x

上面的代码与下面的式子作用一样:

请时刻注意代码的可读性。