首页/开发/正则与编码速查/问号量词与可选匹配的写法
正则基础45 条

问号量词与可选匹配的写法

问号既是「出现零次或一次」的量词,也是把其他量词改成非贪婪的修饰符,写在左括号后则构成特殊分组前缀。同一符号的三种角色由所处位置决定,是模式可读性最容易被破坏的地方。

正则与编码速查开发更新于 2026-10-17
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌​​‌​‌‌‌‌​‌‌‌​​‌​​‌‌​​‌​‌​‌‌​​‌‌‌​‌‌​​‌​‌​‌‌‌‌​​​​​‌​‌‌‌‌​‌‌‌​​‌​​‌‌​​‌​‌​‌‌​​‌‌‌​‌‌​​‌​‌​‌‌‌‌​​​​​‌​‌‌​‌​‌‌‌​​​‌​‌‌‌​‌​‌​‌‌​​​​‌​‌‌​‌‌‌​​‌‌‌​‌​​​‌‌​‌​​‌​‌‌​​‌‌​​‌‌​‌​​‌​‌‌​​‌​‌​‌‌‌​​‌​​​‌​‌‌​‌​‌‌‌​​​‌​‌‌‌​‌​‌​‌‌​​‌​‌​‌‌‌​​‌‌​‌‌‌​‌​​​‌‌​‌​​‌​‌‌​‌‌‌‌​‌‌​‌‌‌​​​‌​‌‌​‌​‌‌​‌‌​‌​‌‌​​​​‌​‌‌‌​​‌​​‌‌​‌​‌‌​​‌​‌‌‌​​‌‌​‌​​​​‌‌‌​‌​​​‌‌​‌‌​‌​‌‌​‌‌​​

问号的两种身份

问号的第一重身份是量词:前面的元素出现零次或一次,也就是可选。第二重身份是修饰符:紧跟在其他量词后面,把它从贪婪改成非贪婪。同一个符号在两种位置上的含义完全不同,判断依据是它前面有没有别的量词。

与分组的纠葛

问号还参与构成特殊分组,例如圆括号里以问号开头表示非捕获、断言或命名分组。所以看到括号内问号时,它读作语法前缀而不是量词,这也是模式里问号最难一眼读懂的原因。

基本信息

量词含义前一元素出现 0 到 1 次
修饰含义紧跟量词之后表示非贪婪版本,如星号问号、加号问号
分组前缀圆括号内以问号开头时表示特殊分组构造
等价写法可选字符用花括号写 0 到 1 次完全等价
默认风格作为量词时依然贪婪,会优先尝试吃掉一个字符

典型使用场景

  • 匹配可选的协议头,例如网址中可能出现的安全传输前缀
  • 处理英式与美式拼写差异,把可选的字母用问号包起来
  • 匹配可能带正负号的数值,符号部分设为可选
  • 把贪婪量词改成非贪婪,限定提取范围
  • 匹配带可选尾缀的标识,例如可能出现的单位或后缀

可选与非贪婪的写法

可选与非贪婪的写法
import re
re.findall(r'colou?r', 'color colour')      # 可选字母:两种拼写都命中
re.findall(r'-?\d+', 'a-12 b34')            # 可选负号,匹配带符号数字
re.search(r'https?://', 'http://x')         # 协议头中可选的 s
re.search(r'<i>(.*?)</i>', '<i>a</i>')      # 问号在这里是把星号变非贪婪
re.search(r'\d{0,1}', '7')                  # 与问号完全等价的区间写法
re.search(r'(?:ab)?', 'x ab')               # 非捕获分组整体可选

问号位置的含义

出现位置读作示例效果
字符或类之后量词,出现零或一次可选字母、可选符号
另一个量词之后非贪婪修饰改最短匹配策略
左括号之后特殊分组前缀非捕获、断言或命名分组
字符类内部普通字符不再有量词含义
非贪婪不是「尽量少」的绝对承诺:它只是改变尝试顺序,如果最短方案会导致后面匹配失败,仍然会退回取更长的内容。要严格控制长度,还得靠明确的区间量词或断言。
可选修饰符可以叠加在花括号量词上,例如限定 1 到 3 次再改成非贪婪。写这种组合时建议在模式里保留注释或改写成自由间距模式,避免后续维护者误读。

易错点

  • 把非贪婪当成硬性长度上限,结果最短方案不成立时仍取到更长内容
  • 在括号内误写问号,本想做量词却变成特殊分组前缀,模式直接报错或语义改变
  • 对已经可选的元素叠加非贪婪,写出语义冗余的组合,读起来难以判断到底允许几次
  • 在字符类内使用问号并以为能表示可选,类内问号只是普通字符

数据来源与参考

  • PCRE2 官方文档 pcre2pattern(3):量词与非贪婪修饰符
  • Python 官方文档 re 模块:重复运算符与分组构造
  • MDN JavaScript 参考:量词与断言语法

整理校对:其其网ICT文档中心 · 本页地址:docs.qiqicto.com/regex/regex-quantifier-question-mark.html

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌​​‌​‌‌‌‌​‌‌‌​​‌​​‌‌​​‌​‌​‌‌​​‌‌‌​‌‌​​‌​‌​‌‌‌‌​​​​​‌​‌‌‌‌​‌‌‌​​‌​​‌‌​​‌​‌​‌‌​​‌‌‌​‌‌​​‌​‌​‌‌‌‌​​​​​‌​‌‌​‌​‌‌‌​​​‌​‌‌‌​‌​‌​‌‌​​​​‌​‌‌​‌‌‌​​‌‌‌​‌​​​‌‌​‌​​‌​‌‌​​‌‌​​‌‌​‌​​‌​‌‌​​‌​‌​‌‌‌​​‌​​​‌​‌‌​‌​‌‌‌​​​‌​‌‌‌​‌​‌​‌‌​​‌​‌​‌‌‌​​‌‌​‌‌‌​‌​​​‌‌​‌​​‌​‌‌​‌‌‌‌​‌‌​‌‌‌​​​‌​‌‌​‌​‌‌​‌‌​‌​‌‌​​​​‌​‌‌‌​​‌​​‌‌​‌​‌‌​​‌​‌‌‌​​‌‌​‌​​​​‌‌‌​‌​​​‌‌​‌‌​‌​‌‌​‌‌​​