PHP 正则表达式

362 阅读2分钟

1. 概念

1.1. 正则表达式是一种字符串搜索和匹配的工具

1.2. 各种编程语言对正则表达式都有良好的支持

2. 语法

2.1. 分隔符

2.1.1. 分隔符表示正则表达式的开始和结束

2.1.2. 分隔符可以是除字母、数字、反斜杠、空白符号外的任意字符,经常使用正斜杠 / 、hash 符号 # 、取反符号 ~ 

/模式/

#模式#

~模式~

2.1.3. 如果模式中包含与分隔符相同的字符,可以使用 \ 对与分隔符相同的字符进行转义;也可以使用其它分隔符代替

2.2. 原子

2.2.1. 原子是正则表达式的最小匹配单位

2.2.2. 原子分为可见原子和不可见原子

2.2.2.1. 可见原子:Unicode 编码表中可见的字符

  • 非英文字符:需要转换为 Unicode 编码
  • 用作元字符的符号:需要在前面添加 \ 进行转义

2.2.2.2. 不可见原子:Unicode 编码表中不可见的字符

  • 空格: 
  • 制表符:\t
  • 换行符:\n
  • 回车:\r

2.3. 元字符

2.3.1. 元字符是模式中具有特殊含义的字符

2.3.2. 按照使用场景分类

2.3.2.1. 在 [ ] 外使用的元字符

\:转义字符
^ :断言目标的开始位置,即行首
$ :断言目标的结束位置,即行尾
. :匹配除换行符外的任意字符
| :可选分支
( ) :子组
[ ] :字符类
{ } :量词
? :量词,匹配 0 个或 1 个
* :量词,匹配 0 个、 1 个或多个
+ :量词,匹配 1 个或多个
? :在量词之后使用,表示贪婪匹配和懒惰匹配的转换

2.3.2.2. 在 [ ] 内使用的元字符

\:转义字符
^ :作为第一个字符使用,表示字符类取反
- :标记字符范围

2.3.3. 按照功能分类

2.3.3.1. 边界控制

^ :断言目标的开始位置,即行首
$ :断言目标的结束位置,即行尾

2.3.3.2. 字符类

  • 一个字符类匹配一个字符
[ ] :中括号中的任意字符
[^ ] :除中括号中的字符外的任意字符
. :除换行符外的任意字符
\d :任意数字
\D :任意非数字
\s :任意空白字符
\S :任意非空白字符
\w :任意单词字符,即任意字母、数字、下划线
\W :任意非单词字符,即除字母、数字、下划线外的任意字符

2.3.3.3. 量词

{n} :恰好匹配 n 个
{n,} :至少匹配 n 个
{m,n} :至少匹配 m 个,至多匹配 n 个
? :量词,匹配 0 个或 1 个
* :量词,匹配 0 个、 1 个或多个
+ :量词,匹配 1 个或多个
? :在量词之后使用,表示贪婪匹配和懒惰匹配的转换

2.4. 模式修饰符

2.4.1. 在结束的分隔符后面可以添加模式修饰符

2.4.2. 常见的模式修饰符

u :贪婪匹配,尽可能多地匹配(默认)
U :懒惰匹配,尽可能少地匹配
i :不区分大小写字母
m :多行匹配,^ 和 $ 忽略换行符
s :. 匹配任意字符,包括换行符
x :忽略正则表达式中的空白符号,但不忽略 \s

3. 函数

3.1. 匹配

int preg_match(string 正则表达式, string 目标数据[, array &匹配结果])
  • 函数 preg_match() 匹配字符串中第一个符合要求的子字符串
  • 参数 匹配结果 是一维数组,保存匹配结果
    • 匹配结果[0] 保存模式的匹配结果
    • 当 n > 0 时,匹配结果[n] 保存第 n 个子组的匹配结果
  • 返回值是匹配数量
int preg_match_all(string 正则表达式, string 目标数据[, array &匹配结果])
  • 函数 preg_match_all() 匹配字符串中所有符合要求的子字符串
  • 参数 匹配结果 是二维数组,保存匹配结果
    • 匹配结果[0][n] 保存模式的匹配结果
    • 当 m > 0 时,匹配结果[m][n] 保存第 m 个子组的匹配结果
  • 返回值是匹配数量

3.2. 筛选

array preg_grep(string 正则表达式, array 目标数据)
  • 函数 preg_grep() 筛选出能够发生匹配的数组元素
  • 返回值是发生匹配的数组元素组成的数组

3.3. 替换

mixed preg_replace(mixed 正则表达式, mixed 替换内容, mixed 目标数据)
  • 函数 preg_replace() 将字符串或数组中的所有匹配结果进行替换
  • 参数 正则表达式 和 替换内容 可以同时是字符串或数组
  • 参数 目标数据 可以是字符串或数组
  • 参数 替换内容 中的特殊字符 nn 、{n} 、\n 、{n}
    • 当 n = 0 时,表示模式的匹配结果
    • 当 n > 0 时,表示第 n 个子组的匹配结果
  • 返回值是替换后的字符串或数组

3.4. 筛选并替换

mixed preg_filter(mixed 正则表达式, mixed 替换内容, mixed 目标数据)
  • 函数 preg_filter() 筛选出能够发生匹配的字符串或数组元素,并进行替换
  • 参数 正则表达式 和 替换内容 可以同时是字符串或数组
  • 参数 目标数据 可以是字符串或数组
  • 参数 替换内容 中的特殊字符 nn 、{n} 、\n 、{n}
    • 当 n = 0 时,表示模式的匹配结果
    • 当 n > 0 时,表示第 n 个子组的匹配结果
  • 返回值是发生替换的字符串或数组
    • 当参数 目标数据 是字符串时,如果发生替换,返回值是替换后的字符串;如果没有发生替换,返回值是 null
    • 当参数 目标数据 是数组时,返回值是发生替换的数组元素组成的数组

3.5. 分割

array preg_split(string 正则表达式, string 目标数据)
  • 函数 preg_split() 以所有匹配结果为分割符,将字符串分割为字符串数组

3.6. 转义

string preg_quote(string 字符串[, string 分隔符])
  • 函数 preg_quote() 在字符串中的正则表达式运算符,以及与指定的分隔符相同的字符前面添加 \ ,进行转义
  • 正则表达式运算符:.  \  +  *  ?  [  ^  ]  $  (  )  {  }  =  !  <  >  |  :  -

4. 应用

4.1. 非空:

/.+/ 或 /\S+/

4.2. 数字:

/^[+\-]?\d+(\.\d+)?$/

4.3. 手机:

/^1[3-9]\d{9}$/

4.4. 邮箱:

/^\w+(\.\w+)*@(\w+\.)+[A-Za-z]+$/

4.5. URL:

/^(https?:\/\/)?(\w+\.)+[A-Za-z]+$/

4.6. 靓号:

X+、X+Y+、X+Y+Z+

/^(\d)\1*((\d)\3*)?((\d)\5*)?$/

AABBCCX、XAABBCC

/(11(?=22)|22(?=33)|33(?=44)|44(?=55)|55(?=66)|66(?=77)|77(?=88)|88(?=99)){2,}/

CCBBAAX、XCCBBAA

/(99(?=88)|88(?=77)|77(?=66)|66(?=55)|55(?=44)|44(?=33)|33(?=22)|22(?=11)|11(?=00)){2,}/

XXYYZZU、UXXYYZZ

/(\d)\1(\d)\2(\d)\3/

ABCDEFG、X+ABCD、X+ABCDE、XABCDEF、ABCDY+、ABCDEY+、ABCDEFY

/^((\d)\2+)?(1(?=2)|2(?=3)|3(?=4)|4(?=5)|5(?=6)|6(?=7)|7(?=8)|8(?=9)){3,}\d((\d)\5+)?$/

GFEDCBA、X+DCBA、X+EDCBA、XFEDCBA、DCBAY+、EDCBAY+、FEDCBAY

/^((\d)\2+)?(9(?=8)|8(?=7)|7(?=6)|6(?=5)|5(?=4)|4(?=3)|3(?=2)|2(?=1)|1(?=0)){3,}\d((\d)\5+)?$/

ABCDEFG、X+ABCDE、XABCDEF、ABCDEY+、ABCDEFY、XABCDEY

/(1(?=2)|2(?=3)|3(?=4)|4(?=5)|5(?=6)|6(?=7)|7(?=8)|8(?=9)){4,}/

GFEDCBA、X+EDCBA、XFEDCBA、EDCBAY+、FEDCBAY、XEDCBAY

/(9(?=8)|8(?=7)|7(?=6)|6(?=5)|5(?=4)|4(?=3)|3(?=2)|2(?=1)|1(?=0)){4,}/

ABCDCBA

/^(1(?=2)|2(?=3)|3(?=4)|4(?=5)|5(?=6)|6(?=7)|7(?=8)|8(?=9)){3,}(9(?=8)|8(?=7)|7(?=6)|6(?=5)|5(?=4)|4(?=3)|3(?=2)|2(?=1)|1(?=0)){3,}\d$/

DCBABCD

/^(9(?=8)|8(?=7)|7(?=6)|6(?=5)|5(?=4)|4(?=3)|3(?=2)|2(?=1)|1(?=0)){3,}(1(?=2)|2(?=3)|3(?=4)|4(?=5)|5(?=6)|6(?=7)|7(?=8)|8(?=9)){3,}\d$/

X+、X+Y+、X+Y+X+、X+Y+X+Y+、X+Y+X+Y+X+、X+Y+X+Y+X+Y+、X+Y+X+Y+X+Y+X+

/^(\d)\1*(\d)\2*(\1|\2)*$/

ZXYXYXY、XYXYXYZ

/(\d)(\d)(\1\2){2,}/

5201314、5211314、1314520、1314521

/^(52[01]|1314)+$/

520X+、520X+Y+、520XYXY、521X+、521X+Y+、521XYXY、1314X+、1314X+Y+、X+520、X+Y+520、XYXY520、X+521、X+Y+521、XYXY521、X+1314、X+Y+1314

/^(52[01]|1314)?((\d)\3*((\d)\5*)?)\2*(52[01]|1314)?$/