正则表达式+与*的区别:为何(0*)(\d*)加$后可提取数字?
为什么
(0*)(\d*)加了$锚点才能提取到数字? 嘿,这个问题问到点子上了,咱们得从正则匹配的核心逻辑——贪婪性与匹配优先级——来拆解:
首先明确你的目标字符串:dfdf00023546546,要提取其中的所有数字部分。
1. 为什么(0*)(\d*)直接用不行?
正则匹配的规则是:从左到右扫描,找到第一个能满足正则表达式的匹配就停止,而*表示匹配0次或多次(包括0次)。
那对于(0*)(\d*)来说:
- 扫描到字符串开头的
d时,(0*)可以匹配「0个0」(完全符合*的规则),紧接着(\d*)也可以匹配「0个数字」(同样符合*的规则)。 - 这时候整个正则已经匹配成功了——匹配的是空字符串!正则不会继续往后找更“有用”的匹配,因为它已经找到了第一个合法的结果。所以你自然提取不到想要的数字。
2. 为什么(0*)(\d+)可行?
+表示匹配1次或多次,要求必须至少匹配一个数字。这就改变了匹配逻辑:
- 开头的
dfdf都是非数字,(\d+)根本无法匹配(连1次数字都找不到),所以正则会跳过这些字符,继续往后扫描。 - 直到遇到第一个
0,(0*)会贪婪匹配所有连续的0(也就是000),然后(\d+)匹配剩下的所有数字(23546546)——因为+要求至少一个数字,所以这里必须匹配到有效内容,最终就能提取到你想要的数字部分。
3. 为什么加了$的(0*)(\d*$)就生效了?
$是行尾锚点,它要求正则匹配的内容必须结束在字符串的最后一位。这直接限制了匹配的范围:
- 现在正则不能再在开头匹配空字符串了,因为空字符串不在行尾。它必须找到一个位置,从这个位置开始:
- 先匹配0个或多个
0((0*)) - 再匹配0个或多个数字,且必须一直到字符串结尾(
(\d*$))
- 先匹配0个或多个
- 扫描时,前面的
dfdf是非数字,无法满足(\d*$)(从这里到结尾有非数字),所以正则会跳过这些字符,直到找到数字部分的开头(第一个0)。此时(0*)匹配000,(\d*)匹配剩下的所有数字直到结尾,刚好就是你要的整个数字串。
简单总结:*的“匹配更多”是在同一个匹配位置的贪婪,不是自动跳过前面的无效内容去找最长匹配。没有$时,正则优先找最左边的合法匹配(哪怕是空的);加了$后,强迫正则只能找结束在末尾的匹配,自然就定位到了数字部分。
内容的提问来源于stack exchange,提问作者Nadav
相关产品推荐
相关产品推荐

