0%

正则表达

夏商与西周,东周分两段。春秋和战国,一统秦两汉。三分魏楚吴,二晋前后沿。南北朝并立,隋唐五代传。宋元明清后,皇朝至此完。

一、简介

正则表达式(Regular Expression,简写为regexregexpRE),又称规则表达式,是计算机科学的一个概念,它通常被用来检索、替换那些符合某个模式(规则)的文本。

  1. 正则表达式是用于描述字符排列和匹配模式的一种语法规则。它主要用于字符串的模式分割、匹配、查找及替换操作。
  2. 正则表达式的三个作用:匹配、用新文本代替匹配文本、将一个字符串拆分为一组更小的信息块。
  3. 在PHP中,正则表达式一般是由正规字符和一些特殊字符(类似于通配符)联合构成的一个文本模式的程序性描述。其有两套正则表达式函数库,两者功能相似,只是执行效率略有差异:
    • 一套是由PCRE(Perl Compatible Regular Expression)库提供的,使用preg_为前缀命名的函数
    • 灵一套由POSIX(Portable Operating System Interface of Unix)扩展提供的,使用以ereg_为前缀命名的函数

二、语法分类

  1. 分隔符:当使用 PCRE 函数的时候,模式需要由分隔符闭合包裹,分隔符可以使任意非字母数字、非反斜线、非空白字符。
    • 经常使用的分隔符是正斜线(/)、hash符号(#) 以及取反符号(~)。
  2. 元字符
    • 在模式中方括号外使用(\,^,-)
    • 在模式中方括号内使用(\,^,$,.,[],|,(),{},?,*,+)

三、元字符详解

  1. 转义字符(\),有多种用法

    • 第一种用法是紧接着是一个非字母数字字符,表明取消该字符所代表的特殊涵义。将反斜线作为转义字符的用法在字符类内部和外部都可用
    • 如匹配一个 "*" 字符,就需要在模式中写为"\*"
    • 如匹配一个反斜线,那么在模式中使用”\\”
    • 第二种用法是提供了一种对非打印字符进行可见编码的控制手段
    • 第三种用法是用来描述特定的字符类
    • \d:任意十进制数字
    • \D:任意非十进制数字
    • \w:任意单词字符
    • \W:任意非单词字符
    • \s:任意空白字符
    • \S:任意非空白字符
    • \v:任意垂直空白字符(since PHP 5.2.4)
    • \V:任意非垂直空白字符(since PHP 5.2.4)
    • \h:任意水平空白字符(since PHP 5.2.4)
    • \H:任意非水平空白字符(since PHP 5.2.4)
    • 第四种用法是一些简单的断言
    • \b:单词边界,它匹配的字符串是一个完整的单词
    • \B:非单词边界,它匹配的字串不能是一个完整的单词,而是其他单词或字串的一部分
    • \A:目标的开始位置(独立于多行模式)
    • \Z:目标的结束位置或结束处的换行符(独立于多行模式)
    • \z:目标的结束位置(独立于多行模式)
    • \G:在目标中首次匹配位置
  2. 行定位符(^与$):行定位符是用来描述字符串的边界。

    • “^”表示行开始
    • “$”表示行结尾
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    例一:
    $str = 'abcdddddef124f';
    $search = '/^abc([^xyz]*)$/';
    $result = preg_match_all($search, $str, $match);
    print_r($match);
    Array
    (
    [0] => Array
    (
    [0] => abcdddddef124f
    )

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

    )

    例二:
    $s = 'abcddd';
    $p = '/^abc/';
    $r = preg_match_all($p, $s, $match);
    print_r($match);
    Array
    (
    [0] => Array
    (
    [0] => abc
    )

    )
  3. 句点(.)

    • 匹配目标字符串中的任意字符,包括非打印字符,但是(默认)不包括换行符
    • 如果PCRE_DOTALL被设置,句点就会匹配换行符
    • 句点在字符类中没有任何意义
    • \C可以被用于匹配单字节, 也就是说在UTF-8模式下,句点可以匹配多字节字符。
  1. 字符类([])

    • 一个字符类在目标字符串中匹配一个单独的字符
  2. 可选路径(|)

    • 表示或的意思
    • 注意[]|的区别,[]只能匹配单个字符,而|可以匹配任意长度的字符串
    • 竖线可以在模式中出现任意多个,并且允许有空的可选路径(匹配空字符串)
    • 匹配的处理从左到右尝试每一个可选路径,并且使用第一个成功匹配的
    • 如果可选路径在子组(下面定义)中, 则”成功匹配”表示同时匹配了子模式中的分支以及主模式中的其他部分
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    $s = 'AaaAbAa';
    $p = '/Aa|aA/';
    $r = preg_match_all($p, $s, $match);
    print_r($match);
    Array
    (
    [0] => Array
    (
    [0] => Aa
    [1] => aA
    [2] => Aa
    )

    )
  3. 子组(子模式)

    • 将可选分支局部化
    • 将子组设定为捕获子组,左括号从左至右出现的次序就是对应子组的下标(从1开始)
  4. 重复/量词

    • ?:零次或一次,等价于 {0,1}
    • *:零次或多次,等价于 {0,}
    • +:一次或多次,等价于 {1,}
    • {n}:n次
    • {n,}:至少n次
    • {n,m}:n到m次
  5. 排除字符(^)

    • 表示排除不符合的字符
    • ^一般放在[]中,如[^1-5],该字符不是1~5之间的数字
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    $s = '6789';
    $p = '/[^1-5]/';
    $r = preg_match_all($p, $s, $match);
    print_r($match);
    Array
    (
    [0] => Array
    (
    [0] => 6
    [1] => 7
    [2] => 8
    [3] => 9
    )

    )

库函数

一、PCRE(兼容Perl)

  1. preg_filter — 执行一个正则表达式搜索和替换
  2. preg_grep — 返回匹配模式的数组条目
  3. preg_last_error — 返回最后一个PCRE正则执行产生的错误代码
  4. preg_match_all — 执行一个全局正则表达式匹配
  5. preg_match — 执行匹配正则表达式
  6. preg_quote — 转义正则表达式字符
  7. preg_replace_callback_array — Perform a regular expression search and replace using callbacks
  8. preg_replace_callback — 执行一个正则表达式搜索并且使用一个回调进行替换
  9. preg_replace — 执行一个正则表达式的搜索和替换
  10. preg_split — 通过一个正则表达式分隔字符串

二、POSIX

  1. ereg_replace — 正则表达式替换
  2. ereg — 正则表达式匹配
  3. eregi_replace — 不区分大小写的正则表达式替换
  4. eregi — 不区分大小写的正则表达式匹配
  5. split — 用正则表达式将字符串分割到数组中
  6. spliti — 用正则表达式不区分大小写将字符串分割到数组中
  7. sql_regcase — 产生用于不区分大小的匹配的正则表达式

三、PCRE和POXIS对比

  1. PCRE函数需要模式以分隔符闭合。
  2. 不像POSIX,PCRE扩展没有专门用于大小写不敏感匹配的函数。取而代之的是,支持使用i(PCRE_CASELESS)模式修饰符完成同样的工作。
    • 其他模式修饰符同样可用于改变匹配策略。
  3. POSIX函数从最左面开始寻找最长的匹配,但是 PCRE 在第一个合法匹配后停止。
    • 使用模式 one(self)?(selfsufficient)? 在字符串oneselfsufficient上匹配,PCRE会匹配到oneself,但是使用POSIX,结果将是整个字符串oneselfsufficient。
    • 两个子串都匹配原始字符串,但是 POSIX 将 最长的作为结果。

反向引用

一、概念

  1. 在一个字符类外面,反斜线紧跟一个大于0(可能还有一位数)的数字就是一个到模式中之前出现的某个捕获子组的后向引用,也称反向引用。

二、使用

  1. 例1
1
2
3
4
$str = "aaa.bbb.ccc.ddd.com.cn";
$p = "/(a{3})\.(b{3})(.*)/";
$new = preg_replace($p, '\2.\1\3', $str);
echo $new;// bbb.aaa.ccc.ddd.com.cn

断言

一、概念

  1. 断言是编程术语,表示为一些布尔表达式,程序员相信在程序中的某个特定点该表达式值为真,可以在任何时候启用和禁用断言验证,因此可以在测试时启用断言而在部署时禁用断言。同样,程序投入运行后,最终用户在遇到问题时可以重新启用断言。