开发者社区> 技术小胖子> 正文

在PHP中使用正则表达式进行查找替换

简介:
+关注继续查看
    首先需要声明的是,其实我对正则的应用也不是特别地熟练,只不过是在工作中“被逼无奈”才一步步地对正则有了一些了解。随着对正则的了解越多,越来越发现正则表达式真的是一个很强有力的工具,使用正则,很多时候都可以事半功倍。
    网上流传着很多通用的正则,比如说查找电话号码的正则,查找email的正则。相信也有很多朋友跟我一样,学习正则是从这些流行的正则开始的,当体会到了正则的强大,而这些流行的正则不再合用时,就有了学习正则的动力。其实正则的基本规则很简单,入门很容易,但入门之后怎么来使用却就是各有千秋了。目前PHP支持的正则共有两种:POSIX 扩展的正则表达式和perl兼容的正则表达式。很多PHP的教材上用的都是POSIX扩展的正则表达式,但我却更喜欢perl兼容的正则表达式,一来是因为可以有更好的兼容性,二来是我觉得perl兼容的正则表达式看上去更清晰。
    先来假设一个工作环境:有一个包含用户信息的文件,共有一万行,每行记录一个用户的信息,格式如下:
 username,010-12345678,firstname.lastname,05/21/2007
    下面的文章里,我将以这个假设的工作环境来介绍PHP中perl兼容的正则表达式的查找和替换。
    查找
    最常用的查找是preg_match(),函数说明如下:
    int preg_match_all ( string pattern, string subject, array matches [, int flags] 
    对正则表达式的语法就不多说了,我假设阅读这篇文章的朋友都有一定的正则基础。其实正则表达的查找用处并不是很大,不是太复杂的查找通过可以通过strstr()函数来现实,而且效率更高一些。使用正则的查找通常是一些用strstr()无法实现的比较复杂的查找。例如,我要查找电话号码的区号是010且lastname是bill的一行记录,就可以这么写
 preg_match('/^[^,]*,010[^\.]*\.bill.*$/i',$line);
    其中$line的意思是文件的一行数据。假如$line中的区号是010,lastname又正好是bill,上面的语句就会返回一个非零的正整数,通常我们并不关心这个数的值,而是只关心是否有匹配。又假如我们想找出lastname是bill的用户在2007年的记录,可以用下面的语句
 preg_match('/^[^,]*,[^,]*,[^\.]*\.bill,[^\/]*\/[^\/]*\/2007/i',$line);
    用到正则表达式的替换的地方通常是在需要匹配两个或两个以上的关键字,且这两个关键字不相邻。这个时候无法用正常的查找函数来实现,就用到正则。
    
    替换:相对于查找,我认为替换才是正则表达式最强大、最有用的地方。假设我们现在需要把文件中一万条记录的日期格式换成yyyy/mm/dd,你会怎么做呢?你会发现,普通的查找替换是达不到这个目的了。也许你会说可以把一行的记录分解,进行分析后再重组。我承认这确实是一个解决的办法,可是这并不是最好的解决办法,让我们看一下用正则是怎么来达到我们的要求的:
 $line = preg_replace('/([^,]*,[^,]*,[^,]*,)([0-9]*)\/([0-9]*)\/([0-9]*)/i',"\${1}\${4}\${2}\${3}",$line);
    这里我们使用了正则表达式里的“子模式”,细心观察就可以发现,preg_replace函数的第一个参数里一共有四对‘()’,每一对‘()’里的内容就是一个“子模式”,在第二个参数里可以通过\${1}、\${2}这样的格式来随便组合这些子模式。如我想删除数据里的电话号码,可以这样来写:
 $line = preg_replace('/([^,]*,)([^,]*,)[^,]*,)([0-9]*)\/([0-9]*)\/([0-9]*)/i',"\${1}\${4}\${2}\${3}",$line);
    这里为了介绍子模式而使用了比较复杂的写法,实际上还有一种更简单的方法:
 $line = preg_replace('/,[\d]+\-[\d]+/i','',$line);
    有一句话,忘了是别人说的还是自己原创的,反正在我脑子里好久了:正则表达式不是技术,而是技巧:)正则的入门实际上是相当简单的,用上一两次就能掌握基本的语法,要让这把剑发挥出多大的威力,就看个人的修行了。需要说明的一点是,这把剑实际上也是一把双刃剑:正则的执行效率实际上要比strstr,strpos之类的函数低,所以,当你的查找很简单的时候,就没必要再合用正则了。

     本文转自wfyang 51CTO博客,原文链接:http://blog.51cto.com/wfyang/28637,如需转载请自行联系原作者


版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
VC中的正则表达式使用
对于很多应用,例如文件查询和名称匹配,在html文件中查找匹配的超链接等等 正则表达式自然是最好的解决方法. 不过VC里面竟然不如VBS对于Regular Expression那样有支持, 除非升级到VC.NET(使用拖管C++就可以使用).
993 0
[转]Vi/Vim查找替换使用方法
vi/vim 中可以使用 :s 命令来替换字符串。该命令有很多种不同细节使用方法,可以实现复杂的功能,记录几种在此,方便以后查询。     :s/vivian/sky/ 替换当前行第一个 vivian 为 sky     :s/vivian/sky/g 替换当前行所有 vivian 为 sky   ...
860 0
Visual Studio查找中文的正则表达式
原文: Visual Studio查找中文的正则表达式 经常有这样的需求:项目代码中有一些输出信息是中文写的,不过现在要做国际化,代码""中写的中文都要改成英文。这样就需要将代码中包含中文的字符串都找出来。
959 0
InnoDB索引概述,二分查找法,平衡二叉树
索引是应用程序设计和开发的一个重要方面。如果索引太多,应用的性能可能会受到影响;如果索引太少,对查询性能又会产生影响。要找到一个合适的平衡点,这对应用的性能至关重要。 如果知道数据的使用,从一开始就应该在需要处添加索引。
1131 0
使用正则表达式抓取博客园列表数据
鉴于我在要完成的asp.net MVC 3 仿照博客园企业系统要用到测试数据,我自己输入太累,所以我就抓取了博客园的部分列表数据,还请dudu不要见怪。 在抓取博客园数据的时候采用了正则表达式,所以有不熟悉正则表达式的朋友可以参考相关资料,其实很容易掌握,就是在具体的实例中会花些时间。
950 0
hbase源码系列(五)Trie单词查找树
在hbase当中单独拿了一个工程出来实现了Trie的数据结果,既达到了压缩编码的效果,亦达到了方便查询的效果,一举两得,设置的方法是在上一章的末尾提了。
1578 0
表达式 - PHP手册笔记
原文:表达式 - PHP手册笔记 PHP是一种面向表达式的语言。表达式的定义可以描述为,任何有值的东西。 PHP支持全等运算符===(值和类型均相同)和非全等运算符!==(值或者类型不同)。 PHP的三元条件运算符貌似和C语言不太一样,这里没提,那就先简单略过去吧。 (全文完)
682 0
学习 Linux,101: 使用正则表达式搜索文本文件
概述 本文深入介绍基础的 Linux 进程管理技术。您将学习如何: 创建简单的正则表达式 使用正则表达式搜索文件和文件系统 使用正则表达式和 sed 本文帮助您准备 Linux Professional Institute's Junior Level Administration (LPIC-1) 考试的 103 主题下的 103.7 考核目标。
869 0
21115
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
JS零基础入门教程(上册)
立即下载
性能优化方法论
立即下载
手把手学习日志服务SLS,云启实验室实战指南
立即下载