为何R中stringr::str_extract用\d*无法提取'word 42'里的"42"?
正则匹配结果差异的原因解析
先明确几个核心规则,搞懂这些你就能明白所有案例的结果:
str_extract只会返回从左到右第一个匹配成功的内容\d*:匹配0个或多个连续数字(重点是允许0个,空字符也能匹配)\d+:匹配1个或多个连续数字(必须至少有一个数字才会匹配)$:锚定正则匹配的位置为字符串结尾
逐个案例拆解
案例1:str_extract('word 42', '\d*') → 返回""
正则从字符串最左端开始匹配:第一个字符是w,不是数字,但\d*允许匹配0个数字,这就构成了一个合法的匹配项(空字符串)。因为str_extract找第一个匹配结果,所以直接返回空,不会继续往后找真正有数字的部分。
案例2:str_extract('42 word', '\d*') → 返回"42"
正则从左端开始,第一个字符是4,属于数字,\d*会贪婪匹配所有连续的数字,直到遇到非数字的空格为止,所以匹配到42,这是第一个匹配项,直接返回。
案例3:str_extract('word 42', '\d+') → 返回"42"
\d+要求至少匹配1个数字,左端的字母无法满足,所以正则会继续向右扫描,直到遇到空格后的42,满足匹配条件,因此返回42。
案例4:str_extract('word 42', '\d*$') → 返回"42"
$强制正则在字符串结尾位置匹配。字符串结尾是2,属于数字,\d*贪婪向左匹配所有连续数字,得到42,匹配成功,返回结果。
案例5:str_extract('42 word', '\d*$') → 返回""
字符串结尾是d,不是数字,\d*只能匹配0个数字(空字符串),所以返回空。
正确提取数字的方法
如果你的需求是提取字符串中的数字(不管位置),直接用\d+即可,它会跳过非数字内容,找到第一个连续数字序列:
str_extract('word 42', '\\d+') # 返回"42" str_extract('42 word', '\\d+') # 返回"42"
如果要提取所有数字序列,用str_extract_all:
str_extract_all('word 42 test 123', '\\d+') # 返回list(c("42", "123"))
内容的提问来源于stack exchange,提问作者George Pak
相关产品推荐
相关产品推荐

