前言

最近在系统的学习 PHP ,参考的资料是《PHP编程》+ 官方文档(如果你有好的学习资料,欢迎推荐给我)。虽然这本《PHP编程》是基于 PHP5 的,但我笔记里的代码,全部在 PHP 7.2 的环境里测试过,是能够运行的。另,本笔记中只记录我模糊不清的知识。

基础

. : 匹配任意单个字符

  1. var_dump(preg_match("/c.t/", "cat")); // true
  2. var_dump(preg_match("/c.t/", "c t")); // true
  3. var_dump(preg_match("/c.t/", "b t")); // false
  4. var_dump(preg_match("/c.t/", "ct")); // false

匹配特殊字符(元字符)要使用反斜杠进行转义

  1. var_dump(preg_match("/\\$5\\.00/", "Your bill is $5.00 exactly")); // true
  2. var_dump(preg_match("/$5.00/", "Your bill is $5.00 exactly")); // false

正则表达式中,有三种基本的抽象模式:

  • 在字符串中可以出现的字符集(字母、数字和特殊的标点符号)
  • 可选择的字符串集合(例如“com”、“edu”、“net”)
  • 在字符串中重复的序列(至少一个但是不多于5个数字字符)

    锚( anchor )将匹配限制在字符串中的特定位置(锚不匹配目标字符串中的实际字符)

| 锚 | 匹配 | | —- | —- |

| ^ | 字符串开始 |

| $ | 字符串结尾 |

| [[:<:]] | 单词开始 |

| [[:>:]] | 单词结尾 |

| \b | 单词边界(\w和\W之间或者字符串的开头、结尾) |

| \B | 非单词边界(\w\w之间或者\W\W之间) |

| \A | 字符串开始 |

| \Z | 字符串结尾,或者换行符 \n 之前 |

| \z | 字符串结尾 |

| ^ | 一行的开头(如果/m标签生效,换行符\n后面) |

| $ | 一行的结尾(如果/m标签生效,换行符\n前面) |

^ : 匹配到字符串的开头

  1. preg_match("/^cow/", "Dave was a cowhand"); // false
  2. preg_match("/^cow/", "cowabunga"); // true

$ : 匹配到字符串的结尾

  1. var_dump(preg_match("/cow$/", "Dave was a cowhand")); // false
  2. var_dump(preg_match("/cow$/", "Don't have a cow")); // true

字符类

通过中括号包含可接受的字符类

| 类 | 描述 | 扩展 | | —- | —- | —- |

| [:alnum:] | 字母和数字字符 | [0-9a-zA-Z] |

| [:alpha:] | 字母字符 | [a-zA-Z] |

| [:ascii:] | 7位的 ASCII 码 | [\x01-\x7F] |

| [:black:] | 水平空白符 | [ \t] |

| [:cntrl:] | 控制字符 | [\x01-\x1F] |

| [:digit:] | 数字 | [0-9] |

| [:graph:] | 用墨水打印的字符 | [^\x01-\x20] |

| [:lower:] | 小写字母 | [a-z] |

| [:print:] | 可打印的字符(图形类、空格和制表符) | [\t\x20-\xFF] |

| [:punct:] | 任意标点符号 | [-!”#$%_{|}~] |

| [:space:] | 空白字符 | [\n\r\t \x0B] |

| [:upper:] | 大写字母 | [A-Z] |

| [:xdigit:] | 十六进制数 | [0-9a-fA-F] |

| \s | 空白 | [\r\n \t] |

| \S | 非空白 | [^\r\n \t] |

| \w | 单词字符 | [0-9a-zA-Z_] |

| \W | 非单词字符 | [^0-9a-zA-Z_] |

| \d | 数字 | [0-9] |

| \D | 非数字 | [^0-9] |

  1. var_dump(preg_match("/c[aeiou]t/", "I cut my hand")); // true
  2. var_dump(preg_match("/c[aeiou]t/", "What cart")); // false 中间由两个字符
  3. var_dump(preg_match("/c[aeiou]t/", "14ct gold")); // false 中间没有字符
  4. //在字符类开头使用 ^ 来否定这个字符类
  5. var_dump(preg_match("/c[^aeiou]t/", "I cut my hand")); // false
  6. //用连接符( - )定义一个字符范围
  7. var_dump(preg_match("/[0-9]%/", "25%")); // true
  8. var_dump(preg_match("/[a-zA-Z]!/", "stop!")); // true
  9. var_dump(preg_match("/[a-zA-Z]!/", "stop")); // false

选择性

使用竖线( | )字符在正则表达式中指定可选择的部分

  1. var_dump(preg_match("/^([a-z]|[0-9])/", "The quick brown fox")); // false
  2. var_dump(preg_match("/^([a-z]|[0-9])/", "jumped over`")); // true

重复序列

| 量词 | 意义 | | —- | —- |

| ? | 0 次或 1 次 |

| * | 0 次或多次 |

| + | 1 次或多次 |

| { n } | 出现 n 了 |

| { n , m } | 最少 n 次,不超过 m 次 |

| { n , } | 最少 n 次 |

  1. var_dump(preg_match("/ca+t/", "caaaaaaaaaat")); // true

子模式

使用小括号把正则表达式组合在一起,作为一个单独的单元来处理。可以指定第三个参数传递给匹配函数,第三个参数将会被返回一个数组。数组第 0 个元素设置为匹配的整个字符串,第一个元素是与子模式匹配的第一个子字符串,第二个元素是与子模式匹配的第二个子字符串,以此类推。
如果你不想捕获匹配到的文本,可以用(?:subpattern)的结构来实现

  1. preg_match("/([0-9]+)([a-z]+)/", "1234yii", $good);
  2. var_dump($good[1]); // 1234
  3. var_dump($good[2]); // yii
  4. preg_match("/(?:[0-9]+)([a-z]+)/", "1234yii", $good);
  5. var_dump($good[1]); // yii

量词和贪婪

正则表达式中的量词是贪婪的,所以提供了一种模式来使得量词支持最少匹配模式。

| 贪婪量词 | 非贪婪量词 | | —- | —- |

| ? | ?? |

| | ? |

| + | +? |

| { n } | { n }? |

| { n , } | { n , }? |

| { n , m } | { n , m }? |

  1. var_dump(preg_match("/(<.*>)/", "do <b>not</b> press the button", $match));
  2. var_dump($match[1]); // <b>not</b>
  3. var_dump(preg_match("/(<.*?>)/", "do <b>not</b> press the button", $match));
  4. var_dump($match[1]); // <b>

逆向引用

使用逆向引用 \1 ,来引用某个模式里面匹配到的第一个文本,\2 来引用第二个,以此类推。

  1. preg_match("/([[:alpha:]]+)\s+\\1/", "Paris in the the spting", $good); // 这里的\\1 就相当于 ([[:alpha:]]+)
  2. var_dump($good); // 结果返回如下
  3. array(2) {
  4. [0]=>
  5. string(7) "the the"
  6. [1]=>
  7. string(3) "the"
  8. }

后缀选项

正则表达式允许你把字符放在正则表达式的后面,从而改变表达式的解析、行为或者匹配方式。

| 修饰符 | 意义 | | —- | —- |

| /regexp/i | 匹配大小写 |

| /regexp/s | 使句点匹配任何字符,包括换行符\n |

| /regexp/x | 去掉空白和注释 |

| /regexp/m | 使得( ^ )匹配换行符\n之后的内容,( $ ) 匹配换行符\n之前的内容 |

| /regexp/e | 如果替换字符串是 PHP 代码,使用 eval() 执行该代码,得到实际替换的字符串 |

| /regexp/U | 颠倒子模式的贪婪性。* 和 + 尽可能少地匹配而不是尽可能多 |

| /regexp/u | 把模式字符串当作 UTF-8 编码 |

| /regexp/X | 如果一个反斜杠之后跟着没有特殊意义的字符,则产生一个错误 |

| /regexp/A | 把锚定位在字符串的开头就像模式中由 ^ 一样 |

| /regexp/D | 使 $ 字符仅匹配一行的末尾 |

| /regexp/S | 使表达式解析器更小心地检查模式的结构,使得第二次运行时(如在一个循环中),加快速度 |

  1. $message = <<< END
  2. To: you@youcorp
  3. From: me@mecorp
  4. Subject: pay up
  5. pay me or else!
  6. END;
  7. var_dump(preg_match("/^subject: (.*)/im", $message, $good)); // true
  8. var_dump($good[1]); // pay up

除了在模式结束分隔符之后指定模式选项之外,还可以在一个模式内部指定仅运行于部分模式的选项。语法为:(?flags:subpattern)

  1. var_dump(preg_match("/I like (?ix:ph p)/", "I like pHp")); // true

正则表达式的相关函数

匹配

  • preg_match(pattern, string[, &matches]):int : 搜索 stringpattern 给定的正则表达式的一个匹配。如果提供 matches 参数,它将被填充为搜索结果,$matches[0] 将包含完整模式匹配到的文本,$matches[1] 将包含第一个捕获子模式匹配到的文本,以此类推。
  • perg_match_all() : 与 preg_match() 参数相同,不同的是 preg_match() 在第一次匹配后停止搜索,preg_match_all() 会一直搜索到结尾。

    替换

  • preg_replace(pattern, replacement, subject[, limit = -1]):mixed : 搜索 subject 中匹配 pattern 的部分,以 replacement 进行替换。limit : 每个模式在每个 subject 上进行替换的最大次数。默认是 -1 (无限)。

  • preg_replace_callback(pattern, callable, subject[, limit = -1]):mixed : 与 preg_replace() 不同的是,可以指定一个 callback 替代 replacement 进行替换字符串的计算。

    拆分

  • preg_split(pattern, subject[, limit=-1[, flags=0]]):array : 通过一个正则表达式 pattern 分割字符串 subject

    使用正则表达式过滤数组

  • preg_grep(pattern, array[, flags=0]):array : 返回给定数组 array 中模式 pattern 匹配的元素组成的数组。

    引用正则表达式

  • preg_quote(string[, delimiter=NULL]):string : 返回字符串 string 的正则表达式。注意:默认不会转义 /,需指定第二个参数为 / 才可以被转义。

感谢你看到了这里。如果文章有错误,请评论指正,谢谢!