正则表达式
- Regula Expression;通常缩写成“regex”,单数有regexp、regex,复数有regexps、regexes、regexen。
- 是用于描述[字符]>>[排列]和[匹配]模式的 1 种语法[规则];
- 主要运用在[字符]>>[分割],[匹配],[查找],[替换]等操作;
- 在php里使用的perl语言里的正则表达式引擎;
- 一般是由正规字符串和一些特殊字符联合构成的一个文本模式的程序性描述;
- 正则匹配 默认是 贪婪的
正则表达式的构成
模式结构: /原子和元字符/模式修正符; / 是分隔符 或称 定界符
分隔符
- 正则表达式模式需要用 分割符 闭合包裹。分隔符可以使任意非字母数字、非反斜线、非空白字符。
- 经常使用的分隔符是正斜线(/)、hash符号(#) 以及取反符号(~)。
- 下面的例子都是使用合法分隔符的模式。
/foo bar/ #^[^0-9]$# +php+ %[a-zA-Z0-9_-]%
- 如果分隔符需要在模式内进行匹配,它必须使用反斜线进行转义。
- 如果分隔符经常在 模式内出现, 一个更好的选择就是是[用其他分隔符来提高可读性]。
/http:\/\// ~http://~
分隔符内的 原子
[匹配得到的字符]
可见字符
- 普通字符 0-9 a-z A-Z
- 符号 ` ~ ! @ # $ % ^ & * ( ) _ - + = [ { } ] ; : ’ ” , . / \ < > ?
- 有涵义的符号出现在模式内需用 \ 转义,消除涵义 [符号涵义请看 元字符]
转义序列(反斜线)
- [要输出反斜线的转义字符,字符串引号必须是双引号]
- 反斜线 - 取消符号特殊涵义:
- \ [后面如果紧接着] 是一个 [非字母数字字符],[表明取消] [该字符所代表的特殊涵义]。
这种将反斜线作为转义字符的用法在字符类内部和外部都可用。 - “/\\/”,首先它作为字符串,反斜线会进行转义,那么转义后的结果是/\/,这个才是正则表达式引擎拿到的模式,
- 而正则表达式引擎也认为 \ 是转义标记,它会将分隔符 / 进行转义,从而得到的是一个错误,因此,需要 4 个反斜线才可以匹配一个反斜线。
- \ [后面如果紧接着] 是一个 [非字母数字字符],[表明取消] [该字符所代表的特殊涵义]。
- 反斜线二 - 非打印字符:
- \a 表示:响铃字符(十六进制 07)
- \cx 表示:”control-x”,x 是任意字符
- 如果x是一个小写字母,它被转换为大写。
- 接着,将字符的第6位(十六进制 40,右数第一个位为第0位)取反。
- 比如:
- \cz 成为十六进制的 1A,
- \c{ 成为十六进制的 3B,
- \c; 成为十六进制的 7B。
- \e 表示:转义 (十六进制 1B)
- \f 表示:换页 (十六进制 0C)
- \n 表示:换行 (十六进制 0A)
- \p{xx} 表示:一个符合 xx 属性的字符,详细查看unicode properties 属性
- \r 表示:回车 (十六进制 0D)
- \t 表示:水平制表符 (十六进制 09)
- \ddd 表示:ddd八进制编码的字符,或者后向引用
- \040 空格的另外一种用法
- \40 当提供了少于40个子组时也认为是空格。
- \7 始终是后向引用
- \11 可能是后向引用,也可能是制表符
- \011 总是一个制表符
- \0113 一个制表符紧跟着一个3(因为每次最多只读取3个8进制位
- \113 八进制113代表的字符
- \377 8进制377是10进制255, 因此代表一个全1的字符
- \81 一个后向引用或者一个二进制 0 紧跟着两个数字 8 和 1(因为8不是8进制有效数字)
- 反斜线三 - 描述特定的字符类:
- \d 表示:任意一个 十进制数【字符】
- \D 表示:任意一个 非 十进制数【字符】
- \w 表示:任意一个 字母,数字,下划线【字符】
- \w 表示:任意一个 非 字母,数字,下划线【字符】
- \s 表示:只是一个 空白【字符】
- \S 表示:任意一个 非 空白【字符】
- \h 表示:只是一个 水平空白【字符】
- \H 表示:任意一个 非 水平空白【字符】
- \v 表示:只是一个 垂直空白【字符】 (它的作用是让‘\v’后面的【字符】从下 1 行开始输出,且开始的列数为“\v”前 1个【字符】所在列后面 1 列)
- \V 表示:任意一个 非 垂直空白【字符】
- 反斜线四 - 位置:
- \b 表示:字符串边缘位置(字符前面或字符后面; 没有相连字符,对于\b来说空白不是字符)
- \B 表示:非字符串边缘位置
- \A 表示:目标的开始位置(独立于多行模式)
- \z 表示:目标的结束位置(独立于多行模式)
- \Z 表示:目标的结束位置或结束处的换行符(独立于多行模式)
- \G 表示:在目标中首次匹配位置
分隔符内的 元字符
[带涵义的符号]
- . 除 \r回车 \n换行 之外的 任何 单个字符。
- \ 一般用于转义字符
- ^ 断言目标的开始位置(或在多行模式下是行首)
- $ 断言目标的结束位置(或在多行模式下是行尾)
- - 连字符 只有使用在数字或字母中间时,才表示范围之间的数字或字母
- | 开始一个可选分支
- * 量词,表示对前面原子或原子单元的 0 次 或 多次 匹配
- + 量词,表示对前面原子或原子单元的 1 次 或 多次 匹配
- \? 量词,表示对前面原子或原子单元的 0 次 或 1 次 匹配。位于量词后面用于改变量词的贪婪特性。
- [ 开始字符类定义
- ] 结束字符类定义 [a-z] 表示26个小写字母其中的一个 [^] 非范围内
- ( 子组的开始标记
- ) 子组的结束标记 (a-z) 表示26个小写字母
- { 自定义量词开始标记
- } 自定义量词结束标记 {匹配次数} {1,2} 匹配1次到2次 作用于前面的字符 或 字符单元
分隔符后的 模式修正符
[写在模式分隔符后面,表示对匹配模式的修正]
i 执行[不区分大小写]字母的匹配
如: "/abc/i" 可以与abc或aBC或ABc等匹配;
g 对>对象[全局匹配],简言之,把对象从头匹配到尾,而不是在找到第一个之后就停止的模式
m [多行匹配模式]
正则模式默认是对当前行字符串匹配的。 ———————————————————————————————————————————————— ^匹配[一行的开头和字符串的开头],$匹配[一行的结束和字符串的结束] ———————————————————————————————————————————————— 那比如 \n换行 \r回车
\v垂直制表符等导致的多行字符串如何匹配呢?
'/java\njava/'; 两行字符串,\n换行导致后面的java在下一行,\n在双引号里才能[输出]换行符 '/java$/m'; 可以匹配多行字符串里的行结尾的java 例: 匹配模式: $mode="/abc/m"; 匹配对象: $str="bcefg5e\nabcdfe" // 注意其中\n,换行了;abc换到了下一行; $str 和 $mode 仍可以匹配成功,修正符 m 使得多行也可匹配;
s 将字符串对象视为单行,[忽略了字符串中的换行]类字符
例: 匹配对象: $str="pr\ny"; 匹配模式: $mode="/pr.y/"; 两者不可匹配; . 是除了换行以外的字符可匹配; 修改下模式为: $mode="/pr.y/s"; 其中修正符 s 将 \n 忽略了; 最后两者可以匹配;
- x 将模式中的空白忽略
A 强制从目标字符串开头匹配
例: 匹配模式: $mode="/abc/A"; 匹配对象: $str="abcsdfi" 匹配, $str2="sdsdabc" 不匹配; 因为 $str2 不是以 abc 开头;
D 限制结尾字符,则不允许结尾有换行
例: 匹配模式: $mode="/abc$/"; 匹配对象: $str="adshabc\n"; 可以与最后有换行的匹配 元子符 $ 会忽略最后的换行 \n; 如果模式为: $mode="/abc/D", 则不能与 $str="adshabc\n" 匹配, 修正符 D 限制其不可有换行;必需以 abc 结尾;
U 只匹配最近的一个字符串;不重复匹配,[最小程度的匹配-贪婪模式]
例1: 对象:$str="abcabbbcabbbbbc" ; 模式:$mode="/a.*c/"; preg_match($mode,$str,$content); // 参1 匹配模式, 参2 匹配对象, 参3 接收数据的变量 echo $content[0]; //输出:abcabbbcabbbbbc; 如果 $mode="/a.*c/"; 变成 $mode="/a.*c/U"; 则只匹配最近一个字符串,输出:abc;比较细化
e 字符串表达式(eval模式),只配合正则替换函数 preg_replace() 使用,替换引用的匹配值变成了表达式字符串
例: $str11 = '123 php'; $ptn11 = '/(\d+)(\s)(\w+)/e'; // eval() // 字符串表达式,把匹配到的字符串按其自身所表达的方式执行 $reg11 = 'strtoupper(\\3).strrev(\\1)'; // 匹配引用模式 $0及\\0为模式整体匹配值,$1及\\1为第一个()子组匹配值,类推 // strtoupper(\\1引用匹配值第一单元) // 表达式把参数字符变成大写 拼接 翻转后的字符串 $str21 = preg_replace($ptn11, $reg11,$str11); // 参数2 替换值 echo nl2br($str21."\n");