问题: 正则表达式中*、+、?的基础含义分别是什么?
👇 点击展开/折叠 面试背诵模板(建议先背这个)
`*`、`+`、`?` 都是正则中的量词(限定符),用于修饰其前面的原子字符或分组,控制该元素出现的次数。`*` 表示匹配前一个字符零次或多次,等价于 `{0,}`;`+` 表示匹配前一个字符一次或多次,等价于 `{1,}`;`?` 表示匹配前一个字符零次或一次,等价于 `{0,1}`。三者默认均为贪婪匹配模式,即尽可能多地向后匹配字符。
---
三者的量化对比
| 量词 |
语义 |
等价写法 |
记忆口诀 |
* |
零次或多次 |
{0,} |
“可有可无,多多益善” |
+ |
一次或多次 |
{1,} |
“至少一次,上不封顶” |
? |
零次或一次 |
{0,1} |
“要么没有,要么一次” |
1 2 3 4 5 6
| import re print(re.fullmatch(r'a*', '')) print(re.fullmatch(r'a*', 'aa')) print(re.fullmatch(r'a+', '')) print(re.fullmatch(r'a?', '')) print(re.fullmatch(r'a?', 'a'))
|
贪婪匹配的实际影响(常见认知盲区)
默认情况下,这些量词会尽可能多地匹配字符(贪婪)。例如使用 .+ 匹配 "a"b" 时,会匹配整个字符串 "a"b",而非预期中的 "a"。若需最小匹配(懒惰模式),需在量词后追加 ?,即 .+? 或 *?。
1 2 3
| text = "<div>hello</div><span>world</span>" print(re.findall(r'<.*>', text)) print(re.findall(r'<.*?>', text))
|
零次匹配的空值陷阱(面试高频)
由于 * 和 ? 支持零次匹配,当使用 re.match() 或 re.search() 时,即使目标字符串中不存在该字符,匹配也可能成功(返回空字符串对象),从而绕过逻辑校验。例如用 r'\d*' 校验非空数字时,空字符串也会通过,实际开发中应优先使用 + 保证至少一位。
1 2
| print(re.match(r'\d*', 'abc')) print(re.match(r'\d+', 'abc'))
|