打印本页
%06 %704 %2013 %23:%五 %PM

正则表达式详解

作者
给本项目评分
(1 投票)

什么是正则表达式?

正则表达式就是描述字符串排列模式的一种自定义语法规则。比喻$pattern="/(?:https?|ftps?):\/\/(?:www|mail|news)\..+\.(?:com|cn|net)?\.?(?:com|cn|net)?/i";这个正则表达式可以用来匹配URL.

 

关于正则表达式有以下几个说法,可以参考一下:

  1. 如果可以使用字符串处理函数完成的任务,就不要使用正则表达式。这是从处理效率上来讲的。
  2. 有一些复杂的操作,只能够使用正则表达式完成。
  3. 正则表达式可以在很多计算机语言中应用。
  4. 正则表达式也称为一种模式表达式、
  5. 正则表达式就是通过构建具有特定规则的模式,与输入的字符信息比较。再进行分割、匹配、查找、替换等工作。
  6.  如果正则表达式不和函数一起使用,则就是一个字符串,如果将正则表达式,放入到某个函数中使用,才能发挥出正则表达式的作用。
  7. 用到分割函数中 就可以用这个正则去分割字符串。用到替换函数中,就可以用这个正则去替换字符串。
  8. 学习正则表达式要学习两方面。
    • 正则表达式的模式是如何编写的
    • 学习正则表达式的强大处理函数

 正则表达式查用术语

  • 定界符
  • 原子
  • 元字符
  • 脱字符
  • 通配符(正向预查,反向预查)
  • 反向引用
  • 惰性匹配
  • 注释
  • 零字符宽度

定界符

定界符用来表示一个正则表达式的开始开始和结束(也不是正则的结束)举例来说:"/<img\s*src=\".*?\"\>/"  "/<img\s*src=\".*?\"\>/u".其中用红色标记的就是定界符。通常使用"/"来做定界符,也可以用"#"来做定界符。使用"#"还是使用"/"依据个人喜好而定。一个建议是当要匹配的字符串中有很多的"/"字符的时候,就尽量用"#"可以减少代码。使用"#"就不必对"/"进行转义。

广义的来说,字母数字和正斜线以外的任何字符 都可以为定界符。

代码:

//$regex = '/^http:\/\/([\w.]+)\/([\w]+)\/([\w]+)\.html$/i';
$regex = '#^http://([\w.]+)/([\w]+)/([\w]+)\.html$#i';
$str = 'http://www.zmax99.com/test/test.html';

$matches = array();
if(preg_match($regex ,$str ,$matches))
{
	 print_r($matches);
}

分析一下上面的正则表达式:

##表示定界符

^表示只匹配用http:开头的字符串

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

\w表示 匹配字  也就是a-z A-Z 0-9 _

+表示前面的字符必须要有一个,可以有多个。

$表示结尾

i表示忽略大小写 另外x表示忽略空格

()表示将这个作为项单独作为一个结果项返回。

综合上述,这个正则表达式要匹配的字符串是,以http:开头,以.html结尾,并且路径深度为2(“/”的个数)的字符串

Array
(
    [0] => http://www.zmax99.com/test/test.html
    [1] => www.zmax99.com
    [2] => test
    [3] => test
)

 

原子

原子是正则表达式的最基本的组成单位,而且必须至少要包含一个原子。只要一个正则表达式可以单独使用的字符,就是原子。

原子包含:所有打印和非打印字符。所有有意义的字符,想作为原子使用,统统使用”\“转义字符转义。

”\“ 转义字符可以将所有有意义的字符转义成没有意义,也可以将没有意义的字符转义成有意义的字符。

在正则表达式中可以使用一些代表范围的原子:

  • \d : 表示任意一个十进制数字
  • \D: 表示任意一个除数字之外的字符
  • \s: 表示任意一个空格符  [\t\n\r]
  • \S: 表示任意一个非空白
  • \w: 表示a-z A-Z 0-9 _ 
  • \W:匹配非字
  • []:匹配方括号中的任何一个元字符。
  • 匹配所有的奇数/[13579]/
  • 在[]中使用 - 表示一段范围[1-7] 匹配1到7中任意一个
  • [^]表示取反,[^1-7]表示匹配除了1-7之外任意一个原子。

 

元字符  

元字符是一种特殊的字符,是用来修饰原子用的,不可单独出现。

  • *   :表示其前面的原子可以出现的次数是0次1次或者多次
  • +  :表示其前面的原子可以出现1次或者多次,最少一次!
  • ?:表示其前面的原子可以出现0次或者1次…………
  • .  :默认情况下表示除了换行符外任意一个字符
    • 如果.在[]中使用,就表示一个点,不代表其他意思
  • $ :修饰整个字符串 表示以什么结尾。

^ : 修饰整个字符串  表示以什么开头

如果^在表达式的开头,那么就表示以某某字符开头。如果在[]中,那么就表示取反。  

|:表示或关系。

  /a|b/ 表示匹配a或者b 只要在字符串中a或者b出现一次就匹配成功

  /cat|dog/  表示匹配cat 或者dog 二者出现一个就可以了  (特别注意并不是匹配t 和 d)

{} :{m} 用于自己定义前面原子出现的次数 

     /zhang{4}/  指定zhang在字符串中只能出现4次

     {m,}用于指定前面的原子最少出现m次。

     {m,n}要是要出现的次数大于m次 小于 n次

 

():

  •      作为大原子使用。
  •      作为子模式。  
  •       全部匹配放到数组的第一个元素中 ,每一个小括号是一个子模式,按顺序放到数组中。
  •       改变优先级。
  •       取消模式 ;在模式前面加上?:
  •       反向引用。可以在模式中直接将子模式取出,再作为正则表达式的一部分。\1 取第一个子模式  \2取第二个子模式。

\b :用来匹配边界的。表示一个边界。

\B:表示一个非边界。

$pattern0="/is/"

$pattern1 = "/\bis\b"; 两边都有边界

$pathern2 ="/\Bis\b/" ;左边没有边界,右边有边界

$pathern3 ="/\bis\B/" ;左边有边界,右边没有边界

$pathern4 ="/\Bis\B/" ;两边都没有边界

所谓的边界就是空格或者其他的换行符,通俗一点就是不可打印的字符。

$string ="this is island!"; 

如果是$pattern0则匹配所有的is

如果是$pattern1则匹配中间的is     两边都有边界     $string ="this is island!";

如果是$pattern2则匹配左边的is     左边没有边界,右边有边界     $string ="this is island!";

如果是$pattern3则匹配右边的is     左边有边界,右边没有边界    $string ="this is island!";

如果是$pattern4则不匹配   两边都没有有边界 。

脱字符

    "\"叫做逃脱字符。用于转义一些特殊的字符

 

通配符(lookarounds):断言某些字符串中某些字符的存在与否

lookarounds分为两种:

  • lookaheads(正向预查?=)
  • lookbehinds(反向预查?<=)

正向预查相对应的(?!)表示否定的意思。反向预查(?<=)相对于的(?<!)表示否定意思。

 $regex = '/(?<=\d)d(?=[A-Z])/';//d 前面是一个数字,d后面是一个大写字符
 $str='abc00dEfgk';

$matches = array();
if(preg_match_all($regex ,$str ,$matches))
{
	 print_r($matches);

}

 结果:

 

Array
(
    [0] => Array
        (
            [0] => d
        )

)

 字符宽度:零

代码:

 
$regex = '/HE(?=L)LO/i';
$str = 'HELLO';

$matches = array();
if(preg_match_all($regex ,$str ,$matches))
{

	 print_r($matches);

} echo "\n";

结果为无法匹配。

这是因为?=L它断定E后面是一个L字符,但是这个L字符不算子匹配字符串中(感觉有点拗口)。如果将$str换成$str=''HELO“就会匹配。

反向引用

在同一个表达式内的引用叫做反向引用。

代码:

$regex = '/^(zmax)[\s]+is[\s]+\1$/';
$str = 'zmax is zmax';
$matches = array();
if(preg_match_all($regex ,$str ,$matches))
{
	 print_r($matches);
}

结果:

Array
(
    [0] => Array
        (
            [0] => zmax is zmax
        )

    [1] => Array
        (
            [0] => zmax
        )

)

在$regex中使用\1来引用前面第一个括号匹配的zmax

命名结果组(命名捕获组)

格式:(?=<组名>)    命名一个结果组

         (?p=组名)   使用一个结果组的结果 和\1类似。只是在结果中不输出。

代码:

 
//$regex = '/^(zmax)[\s]+is[\s]+\1$/';
$regex = '/^(?Pzmax)[\s]+is[\s]+(?P=who)$/';
$str = 'zmax is zmax';
$matches = array();
if(preg_match_all($regex ,$str ,$matches))
{
	 print_r($matches);
}

结果:

Array
(
    [0] => Array
        (
            [0] => zmax is zmax
        )

    [who] => Array
        (
            [0] => zmax
        )

    [1] => Array
        (
            [0] => zmax
        )

)

这样我们就可以使用一个更加有意义的名称来使用结果了。

惰性匹配

?:如果起那么有限定符,会使用最小的数据。如"*“会选取0个,”+“会选取一个,{3,6}会选取3个。

$str="hellllllllllllllllllll";

$pattern0 = '/hel*/';   匹配 hellllllllllllllllllll(贪婪模式)

$pattern1 = '/hel*?/';  匹配 he

$pattern2 = '/hel+?/';  匹配  hel

$pattern3 = '/hel{3,6}?/';匹配 helll

 

正则表达式的注释

格式:(?# 注释的内容) 。在复杂的正在表达式中使用。增加程序的可读性。

代码:

 
$regex = '/
 	^host=(?<!\.)(?P[\d.]+)(?!\.) (?#主机地址)
	\|
	(?P[\w!@#$$^*()_+\-]+)         (?#用户名)
	\|
	(?P[\w!@#$%^&*()_+-]+)         (?#密码)
         (?!\|)$
            /ix';

$str="host=192.168.1.93|root|test";
$matches = array();
if(preg_match_all($regex ,$str ,$matches))
{
	 print_r($matches);
}

结果:

Array
(
    [0] => Array
        (
            [0] => host=192.168.1.93|root|test
        )

    [host] => Array
        (
            [0] => 192.168.1.93
        )

    [1] => Array
        (
            [0] => 192.168.1.93
        )

    [username] => Array
        (
            [0] => root
        )

    [2] => Array
        (
            [0] => root
        )

    [password] => Array
        (
            [0] => test
        )

    [3] => Array
        (
            [0] => test
        )

)

 

模型修正符

模式修正符的作用是对正则表达式进行调优

  •  模式修正符就是几个字母
  •  可以一次使用一个 ,每一个具有一定的意义

i :在和模式匹配的时候不区分大小写。

m: 默认情况 PHP将字符串视为1行。加上m修正符后 为多行。

s : 视为单行

    . 默认不表示换行符 加上s后就可以表示换行。

x :忽略模式中的空格

e :在替换函数中使用

A:强制模式开头

Z:表示必须以模式结尾

U:取消贪婪模式。

当不支持模式修正符的时候 ,使用?可以解决贪婪模式造成的影响。

PHP中正则表达式配合使用的函数

1,字符串的匹配

preg_match :  第一个参数模式

                      第二个参数要查找的字符串

                      第三个参数存放匹配的模式的字符串。

但这个函数只匹配一次。并不会匹配所有的。preg_match_all 可以匹配所有的字符串。将匹配的结果放在第三个参数中。

 2,在字符串中查找

str_replace:  第一个参数 要查找的字符串

                    第二个参数 要替换为的字符串

                    第三个参数需要替换的字符串

返回替换后的结果。PHP函数strstr()也有类似功能 。strstr函数第一个参数 将被执行查找的字符串。 第二个参数 搜索的内容字符串。返回查找到的字符串以及以后的所有内容。

echo  strstr('this is a test good!','test'); 

输出 test good.

stristr()和上一个一样,只是不用区分大小写。

 

 

阅读 2681 次数 最后修改于 %09 %168 %2014 %11:%五 %AM