你了解正则表达式中“?”的作用吗?

正则表达式中 ? 主要有两种核心用法,一种是基础的量词用法,另一种是高级的非贪婪匹配/特殊修饰用法,下面详细拆解说明:

一、 基础用法:量词 - 匹配前面的元素「0次或1次」(可选匹配)

这是 ? 最基础、最常用的功能,它作为量词,作用于紧邻其左侧的单个正则元素(可以是单个字符、字符类、分组等),表示该元素是可选的------既可以出现1次,也可以不出现(0次),最终匹配结果二选一。

示例说明
  1. 匹配可选字符:比如匹配 "color"(美式拼写)和 "colour"(英式拼写)
    正则表达式:colou?r
    解析:u? 表示字母 u 可选(出现0次或1次),因此能同时匹配 "color"(u出现0次)和 "colour"(u出现1次)。
  2. 匹配可选分组:比如匹配 "手机号"(带区号或不带区号,假设区号是 +86
    正则表达式:(\\+86 )?1[3-9]\\d{9}
    解析:(\\+86 )? 表示整个分组 +86 可选,能匹配 "13800138000"(无区号)和 "+86 13800138000"(有区号)。

二、 高级用法:修饰量词 - 开启「非贪婪匹配」(惰性匹配)

? 紧跟在其他量词(*+{n,}{n,m} 等)之后时,它的作用不再是量词,而是将该量词的默认「贪婪匹配」模式切换为「非贪婪匹配」(也叫惰性匹配)。

核心区别
  • 贪婪匹配(默认):量词会尽可能匹配最多的字符,直到无法满足正则后续条件为止。
  • 非贪婪匹配(? 修饰后):量词会尽可能匹配最少的字符,只要满足正则后续条件就立即停止。
示例说明

以字符串 <div>内容1</div><div>内容2</div> 为例,对比两种匹配模式:

  1. 贪婪匹配(默认,无 ?
    正则表达式:<div>.*</div>
    匹配结果:会一次性匹配整个字符串 <div>内容1</div><div>内容2</div>
    解析:.* 是贪婪匹配,会尽可能匹配最多的字符,直到找到最后一个 </div> 才停止。
  2. 非贪婪匹配(加 ? 修饰)
    正则表达式:<div>.*?</div>
    匹配结果:会分别匹配两个片段 <div>内容1</div><div>内容2</div>
    解析:.*? 是非贪婪匹配,只要找到第一个 </div> 就停止当前匹配,然后继续匹配下一个符合条件的片段。

补充:其他特殊场景(非核心,了解即可)

在部分正则引擎中(如Python的re模块、JavaScript正则),? 还会用于特殊语法的前缀标识,例如:

  • (?i):忽略大小写匹配(修饰符)
  • (?P<name>...):命名分组(Python专属)
  • (?:...):非捕获分组(仅匹配,不保留分组结果)
    这些场景中 ? 是语法标识,不具备上述两种核心功能,需结合具体语法使用。

总结

  1. ? 作为量词 :匹配左侧紧邻元素 0 次或 1 次(实现可选匹配),如 colou?r
  2. ? 作为量词修饰符 :紧跟 */+/{n,} 等量词后,将贪婪匹配转为非贪婪匹配,如 .*?
  3. 额外场景:部分正则引擎中作为特殊语法前缀(如忽略大小写、命名分组等)。
相关推荐
Patrick在香港13 小时前
Python正则表达式实战:解析和验证香港身份证、车牌、电话格式
开发语言·python·正则表达式
吴声子夜歌2 天前
正则指引——Ruby
开发语言·正则表达式·ruby
吴声子夜歌3 天前
正则指引——Golang
开发语言·golang·正则表达式
吴声子夜歌4 天前
正则指引——PHP
开发语言·正则表达式·php
吴声子夜歌5 天前
正则指引——断言
正则表达式
吴声子夜歌6 天前
正则指引——匹配原理
java·正则表达式
吴声子夜歌7 天前
正则表达式——环视
开发语言·正则表达式
吴声子夜歌7 天前
正则表达式——边界
正则表达式
营养充电站8 天前
C++23 新特性在 CLion 中的实战体验
macos·docker·jupyter·正则表达式