当前位置: 首页 > article >正文

PHP 正则表达式 修正符【m s x e ? (?i)】内部修正符 贪婪模式 后向引用 断言【总结篇】

1.正则表达式修正符

在 PHP 中,正则表达式中的修正符(modifier)可以改变模式的行为,使得其功能更加灵活。

1. m 修正符(多行模式)

  • 作用:在多行模式下,^$ 元字符除了匹配整个字符串的开头和结尾外,还可以匹配每一行的开头和结尾
  • 举例: "Hello\nWorld",当使用 /^World/m 时,^ 会匹配 "World" 这一行的开头,而不仅仅匹配整个字符串的开头。

2. s 修正符(单行模式)

  • 作用:使 .(点号)可以匹配所有字符,包括换行符(\n。如果不加此修正符,. 默认匹配除换行符外的所有字符。
  • 举例:假设有字符串 "Hello\nWorld",使用 /Hello.World/s 时,. 可以匹配换行符,因此该正则表达式可以成功匹配整个字符串。

3. x 修正符(忽略模式中的空白字符)

  • 作用:开启“扩展模式”,忽略模式中的空白字符(除非在字符类 [] 内或被反斜杠转义),还会忽略未转义的 # 后的内容直到该行结束。通常用于编写更易读的正则表达式。
  • 举例:正则表达式 /a b c/x 实际上会被解析为 /abc/,即空格被忽略。

4. e 修正符(已废弃,自 PHP 5.5.0 起)

  • 作用:该修正符曾用于 preg_replace() 函数,允许在替换时对替换字符串中的反向引用进行 PHP 代码的执行。由于存在安全性问题,该修正符已被弃用。
  • 替代方案:可以使用 preg_replace_callback() 来实现类似功能。(后文介绍)

5. i 修正符

  • 作用: 匹配过程中不区分大小写。
  • 举例:/abc/i可以匹配"AbC"

6. 非贪婪匹配(使用 ? 实现)

  • 贪婪匹配:正则表达式中的 *+? 默认是贪婪的,即它们会匹配尽可能多的字符。
  • 非贪婪匹配:在贪婪量词后加 ?,可以使匹配变为非贪婪(也称为“最小匹配”),即匹配尽可能少的字符。
  • 举例
    • 贪婪匹配:/a.*b/ 会匹配从第一个 a 开始到最后一个 b 之间的所有内容。
    • 非贪婪匹配:/a.*?b/ 只匹配第一个 a 和第一个 b 之间的最少字符。
总结
  • m:多行匹配,^$ 可以匹配每行的开头和结尾。
  • s:单行模式,. 可以匹配包括换行符在内的所有字符。
  • x:忽略正则中的空白字符,并允许使用注释。
  • e:在替换时允许执行 PHP 代码,现已弃用。
  • ?:与 *+ 搭配使用可以实现非贪婪匹配。

2.贪婪匹配与非贪婪匹配

在正则表达式中,贪婪匹配非贪婪匹配 是两个重要的概念,它们决定了匹配操作在处理多个可能的匹配项时的行为。

1. 贪婪匹配

贪婪匹配(Greedy Matching)是正则表达式的默认行为,即在匹配过程中,量词如 *, +{n,} 会尝试匹配尽可能多的字符。它们会从最早出现的匹配点开始,然后继续匹配更多字符,直到满足整个模式或者没有更多可以匹配的字符

  • 模式: /a.*b/
  • 含义:
    • a:匹配字符 a
    • .*:匹配任意字符(除了换行符),匹配尽可能多的字符。
    • b:匹配字符 b
  • 贪婪行为.* 尽可能多地匹配字符,直到遇到最后一个可能的 b
  • 例子:
    • 字符串:"a123b456b"
    • 匹配结果:"a123b456b"

在贪婪匹配中,.* 会从第一个 a 开始,匹配尽可能多的字符,直到遇到最后一个 b。因此,它匹配整个 "a123b456b"

2. 非贪婪匹配

非贪婪匹配(Lazy Matching),也称为“最小匹配”,是通过在量词后面加上 ? 来实现的。非贪婪匹配的行为是尽可能少地匹配字符,在满足整个模式的前提下只匹配最少的字符

  • 模式: /a.*?b/
  • 非贪婪行为.*? 尽可能少地匹配字符,直到遇到第一个 b 就停止。
  • 例子:
    • 字符串:"a123b456b"
    • 匹配结果:"a123b"

在非贪婪匹配中,.*? 从第一个 a 开始,匹配尽可能少的字符,直到遇到第一个 b 就停止。因此,它只匹配 "a123b"

图示化理解:

  1. 贪婪匹配:
    字符串 a123b456b -> 贪婪正则 /a.*b/ -> 匹配到整个 a123b456b

  2. 非贪婪匹配:
    字符串 a123b456b -> 非贪婪正则 /a.*?b/ -> 匹配到 a123b(尽量少匹配)。

总结

  • 贪婪匹配: /a.*b/ 尽可能多地匹配,从第一个 a 开始匹配到最后一个 b
  • 非贪婪匹配: /a.*?b/ 尽可能少地匹配,从第一个 a 开始匹配到第一个 b

3.(?i) 修正符的解释

在 PHP 的正则表达式中,(?i) 是一个内部修正符,用于指定在正则表达式的某个部分中忽略大小写进行匹配。它等同于我们在正则表达式外部使用修正符 i,只是 (?i) 修正符的效果可以局部应用于特定的子模式

1. 用法说明
  • (?i):内部修正符,表示该部分不区分大小写。
  • 区别:如果使用外部的 i 修正符,则整个模式都不区分大小写;但 (?i) 修正符只影响它所在的子模式。
2. 示例
  • 外部修正符: /abc/i
    • 模式 /abc/i 中的 i 修正符表示整个正则表达式不区分大小写。
    • 它将匹配 "abc""ABC""aBc" 等所有大小写组合。
  • 内部修正符: /a(?i)bc/
    • 模式 /a(?i)bc/ 中的 (?i) 只对其后面的 bc 起作用。
    • 它将匹配 "abc""aBC",但不会匹配 "ABC""Abc",因为 a 仍然区分大小写。
3. 结合其它修正符

与外部修正符相似,内部修正符还包括:

  • x:忽略正则表达式中的空白字符。
  • m:多行模式,使 ^$ 匹配行的开头和结尾,而不仅是字符串的开头和结尾。
  • s:单行模式,使 . 匹配包括换行符在内的所有字符。
  • U:非贪婪模式,默认使用非贪婪匹配。

4.后向引用(Backreference)

后向引用是一种可以在正则表达式中引用之前捕获的子模式的方法。通过在模式中添加圆括号 () 来定义捕获组,PHP 会自动为每个捕获的子模式分配一个编号,这个编号从 1 开始。在后续的模式中,可以使用反斜杠 \n(其中 n 是捕获组的编号)来引用之前的匹配。

1. 示例
  • 模式: /(a)(b)(c)/

    • 这将捕获 abc,它们分别存储在捕获组 1、2、3 中。
    • 可以使用后向引用来重新引用这些捕获的部分,例如 /\1\2\3/ 将匹配 abc
  • 示例:

    • 正则表达式 /(a)(b)\1\2/ 将匹配类似 ab 后跟 ab 的字符串。
    • 在字符串 "abxab" 中,模式 /(a)(b)\1\2/ 将匹配 "abab"
2. 非捕获组

有时我们只想匹配某些内容,但不希望将其存储在捕获组中。这时可以使用非捕获元字符 (?:) 来忽略捕获。

  • 示例: (?:abc) 会匹配 "abc",但不会将其存储为捕获组,因此不会占用编号。

其他的非捕获组符号包括:

  • (?=...)正向肯定断言,匹配在指定位置后必须跟随的内容。
  • (?!...)正向否定断言,匹配在指定位置后不能跟随的内容。
总结
  • (?i):内部修正符,指定模式中的某部分不区分大小写。
  • 后向引用:使用 () 捕获匹配内容,并通过 \n 进行引用。
  • 非捕获组:使用 (?:) 或断言符号来匹配但不保存相关内容。

5.正则表达式中的断言

断言用于定义在某个位置前后必须或不能出现的内容,称为零宽断言(zero-width assertions),因为它们只检查条件,而不会消耗字符。

1. 正向肯定断言(?=...)

正向肯定断言表示匹配某位置后面必须跟随的内容,但这些内容本身并不会成为匹配结果的一部分。

  • 格式: (?=...)
  • 作用: 确保在当前位置之后,有满足断言条件的字符出现。
例子:
  • 正则表达式:/\d(?=\D)/
    • 含义:匹配一个数字(\d),条件是它后面跟随一个非数字字符(\D),但不包含这个非数字字符在匹配结果中。
    • 示例字符串:"123a4b"
    • 匹配结果:["3", "4"]
    "123a4b" 中,"3" 后跟的是字母 "a""4" 后跟的是字母 "b",所以它们符合正向肯定断言的条件。
2. 正向否定断言(?!...)

正向否定断言表示匹配某位置后面不能跟随的内容,即当前位置后如果有符合条件的字符出现,匹配将失败。

  • 格式: (?!...)
  • 作用: 确保在当前位置之后,不能有满足断言条件的字符。
例子:
  • 正则表达式:/\d(?!\d)/

    • 含义:匹配一个数字,条件是它后面不能跟随另一个数字(即确保当前匹配的是最后一个连续数字)。
    • 示例字符串:"123a456b"
    • 匹配结果:["3", "6"]

    "123a456b" 中,"3" 后面不是数字,而是字母 "a""6" 后面也不是数字,而是字母 "b",因此它们符合正向否定断言的条件。

总结
  • 正向肯定断言 (?=...): 匹配某个位置后必须跟随的内容,但不包括该内容在最终匹配中。例如,匹配某个字符后跟随特定字符但不包含它。

  • 正向否定断言 (?!...): 匹配某个位置后不能跟随的内容。例如,匹配某个字符,条件是它后面不允许跟随特定字符。


http://www.kler.cn/news/366644.html

相关文章:

  • Java-图书管理系统
  • 电池的主被动均衡
  • day3:管道,解压缩,vim
  • Nginx、Tomcat等项目部署问题及解决方案详解
  • 关于Docker的docker engine stopped问题解决
  • WPF的UpdateSourceTrigger属性
  • 【C++初阶】一文讲通C++内存管理
  • 力扣第 420 场周赛 3324. 出现在屏幕上的字符串序列
  • Chromium127编译指南 Windows篇 - 使用 GN 工具生成构建文件(六)
  • 【二轮征稿启动】第三届环境工程与可持续能源国际会议持续收录优质稿件
  • 代码随想录day11 栈与队列
  • Android静态变量中的字段被置空了
  • 关键词搜索的“魔法咒语”:用API接口召唤商品数据
  • Ubuntu服务器搭建Tailscale Derp节点
  • 掌握ElasticSearch(四):数据类型、回复体
  • arm架构 ubuntu 部署docker
  • 校园表白墙源码修复版
  • 基于python智能推荐的丢失物品招领网站的制作,前端vue+django框架,协同过滤算法实现推荐功能
  • 【MySQL 保姆级教学】表的约束--详细(6)
  • #渗透测试#SRC漏洞挖掘# 信息收集-Shodan批量扫描
  • 新王Claude 3.5的6大应用场景
  • android 文字绘制
  • 常见的租用服务器类型和费用
  • Vue学习笔记(三、v-cloak、v-text、v-html指令)
  • 南京移动5G-A网络助力固城湖螃蟹高效运输
  • SIP 业务举例之 Call Forwarding - No Answer(无应答呼叫转移)