💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
## 正则表达式 正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。 正则表达式是由 **普通字符**(例如字符 a 到 z)以及 **元字符** 组成的文字模式。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。 ### 分隔符 当使用 PCRE 函数的时候,模式需要由分隔符闭合包裹。分隔符可以使任意非字母数字、非反斜线、非空白字符。 经常使用的分隔符是正斜线(/)、hash符号(#) 以及取反符号(~)下面的例子都是使用合法分隔符的模式。 - /foo bar/ - \#^[^0-9]$\# - +php+ - %[a-zA-Z0-9_-]% ### 元字符 正则表达式的威力源于它可以在模式中拥有选择和重复的能力。 一些字符被赋予特殊的涵义,使其不再单纯的代表自己,模式中的这种有特殊涵义的编码字符称为元字符。 共有两种不同的元字符: 一种是可以在方括号外任何地方使用的,一种是需要在方括号内使用的。 **方括号外使用的元字符:** | 字符 | 描述 | | --- | --- | | \ | 转义字符 | | ^ | 断言目标的开始位置(或在多行模式下是行首) | | $ | 断言目标的结束位置(或在多行模式下是行尾) | | . | 匹配除换行符外的任何字符(默认) | | [ | 开始字符类定义 | | ] | 结束字符类定义 | | \| | 开始一个可选分支 | | ( | 子组的开始标记 | | ) | 子组的结束标记 | | ? | 作为量词,表示 0 次或 1 次匹配。位于量词后面用于改变量词的贪婪特性 | | * | 量词,0 次或多次匹配 | | + | 量词,1 次或多次匹配 | | { | 自定义量词开始标记 | | } | 自定义量词结束标记 | **方括号内使用的元字符:** | 字符 | 描述 | | --- | --- | | \ | 转义字符 | | ^ | 仅在作为第一个字符时,表明字符类取反 | | - | 标记字符范围 | **限定符(量词)** 限定符主要是用来限定每个字符串出现的次数。 | 限定字符 | 含义 | | --- | --- | | ? | 零次或一次,等价于 {0,1} | | * | 零次或多次, 等价于 {0,n}| | + | 一次或多次, 等价于 {1,n} | | {n} | n 次 | | {n,} | 至少 n 次 | | {n,m} | n 到 m 次 | ### 转义序列(反斜线) 表达式中的反斜杠有多重意义,如转义字符、显示非打印的字符、指定预定义的字符集、定义断言。 ** (1)转义字符 ** 转义字符主要是将一些特殊字符转为普通字符。比如要匹配元字符,就需要在他们前面加上反斜线,例如:\?, \^, \$ ** (2)显示非打印字符 ** 非打印字符也可以是正则表达式的组成部分,常见的非打印字符转义序列: | 字符 | 含义 | | --- | --- | | \b | 退格 | | \f | 换页符 | | \n | 换行符 | | \r | 回车符 | | \s | 任何空白字符,包括空格、制表符、换页符等 | | \S | 任何非空白字符 | | \t | 制表符 | | \v | 垂直制表符 | **后向引用** 后向引用依靠子表达式的 ”记忆” 功能,匹配连续出现的字串或是字符。如:(abc)(123)\1\2,表示匹配字符串 abc123abc123 ** (3)指定预定义的字符集 ** | 字符 | 含义 | | --- | --- | | \d | 任意十进制数字 | | \D | 任意非十进制数字 | | \s | 任意空白字符 | |\S | 任意非空白字符 | | \w | 任意单词字符(数字,字母,下划线)| | \W | 任意非单词字符 | ** (4)定义断言 ** 一个断言指定一个必须在特定位置匹配的条件, 它们不会从目标字符串中消耗任何字符。 | 字符 | 含义 | | --- | --- | | \b | 单词边界 | | \B | 非单词边界 | | \A | 目标的开始位置(独立于多行模式)| | \z | 目标的结束位置(独立于多行模式)| | \Z | 目标的结束位置或结束处的换行符(独立于多行模式)| | \G | 在目标中首次匹配位置 | ### 模式修饰符 模式修饰符的作用是设定模式,也就是正则表达式如何解释。php 中主要模式如下: | 修饰符 | 说明 | | --- | --- | | i | 忽略大小写 | | m | 多行文本模式 | | s | 单行文本模式 | | x | 忽略空白字符 | ### 表达式示例 匹配特殊字符,例如:$foo, [abc], c++ /\$foo/ /\[abc\]/ /c\+\+/ 匹配以 face 开头的字符串,例如:facebook /^face/ 匹配以 book 结尾的字符串,例如:facebook /book$/ 表达式将匹配 facebook, gitbook /(face|git)book/ 匹配包含元音的字符串 /[aeiou]/ 匹配英文字母和阿拉伯数字 /[a-zA-Z0-9]/ 匹配非阿拉伯数字 /[^0-9]/ 表达式将匹配 gogle, google, gooogle, goo...ogle /goo*gle/ /goo{0,}gle/ 表达式将匹配 gogle, google /goo?gle/ /goo{0,1}gle/ 表达式将匹配 google,gooogle, goo...ogle /goo+gle/ /goo{1,}gle/ 表达式将匹配 google, gooogle, goooogle /goo{1,3}gle/ 表达式将匹配 gooogle /goo{2}gle/ 表达式将匹配 2017-05-21, 0000-00-00, 1234-56-78 /\d{4}-\d{2}-\d{2}/ 匹配一个完整的单词,例如: tom and jerry /\band\b/ 匹配忽略大小写,表达式将匹配 google, Google, GOOGLE /google/i ### 贪婪匹配与惰性匹配 - 贪婪匹配:就是匹配尽可能多的字符。 - 懒惰匹配:就是匹配尽可能少的字符。 例如使用表达式 `/<div>.*<\/div>/` 匹配字符串 `<div>google</div><div>facebook</div>` - 贪婪匹配返回: `<div>google</div><div>facebook</div>` - 懒惰匹配返回: `<div>google</div>` **注意:** 默认情况下,量词都是 ”贪婪” 的,在量词后面加上?(问号)标记,它就会转换成懒惰匹配。 ### PRCE 函数 ``` <?php $html = <<<EOT {div class="list"}php{/div} {div class="list"}python{/div} {div class="list"}java{/div} EOT; $pattern = '/{div class="list"}(.*?){\/div}/'; preg_match($pattern, $html, $matches); print_r($matches); preg_match_all($pattern, $html, $matches); print_r($matches); $str = '小明的出生日期: 1997-10-01'; $pattern = '/(\d{4})-(\d{2})-(\d{2})/i'; $output = preg_replace($pattern, '$1 年 $2 月 $3 日', $str); echo $output . PHP_EOL; $output = preg_replace_callback($pattern, function($matches){ return "{$matches[1]} 年 {$matches[2]} 月 {$matches[3]} 日"; }, $str); echo $output . PHP_EOL; ?> ``` 参考链接: - [模式语法](http://php.net/manual/zh/reference.pcre.pattern.syntax.php) - [模式修饰符](http://php.net/manual/zh/reference.pcre.pattern.modifiers.php) - [PCRE函数](http://php.net/manual/zh/ref.pcre.php)