stringr::str_extract()无法正确捕获正则第三组匹配实例的问题咨询
stringr::str_extract()无法正确捕获正则第三组匹配实例的问题咨询
嗨,我来帮你拆解下这个问题~
首先得搞清楚str_extract()和你用的在线正则测试器的核心差异:
- 你的在线测试器应该是默认展示了正则里第一个捕获组的内容,而
str_extract()的默认行为是返回整个正则匹配到的完整字符串,不是捕获组里的内容。
看你的正则表达式:^(?:.*?Z84[1-9]{1}){2}(.*?Z84[1-9]{1})
- 整个正则匹配的是从字符串开头,到第三个
Z84[1-9]出现位置的全部内容(也就是你现在得到的"W901 Z846 W903 Z846 W919 Z846") - 而你真正想要的
"W919 Z846",其实是正则里**第一个捕获组(.*?Z84[1-9]{1})**匹配到的内容
我给你两个简单的解决方案:
方案1:用str_match()精准获取捕获组内容
str_match()会返回一个矩阵,第一列是整个匹配的内容,后面的列对应各个捕获组。我们直接取第二列就能拿到目标内容:
library(stringr) string = c("W901 Z846 W903 Z846 W919 Z846 Z941") result <- str_match(string, "^(?:.*?Z84[1-9]){2}(.*?Z84[1-9])")[,2] print(result) # [1] "W919 Z846"
方案2:调整正则,让整个匹配就是目标内容
用正向预查来确保前面已经出现过2次Z84[1-9],然后直接匹配我们想要的部分,这样str_extract()就能直接返回结果:
result <- str_extract(string, "(?<=^(?:.*?Z84[1-9]){2}).*?Z84[1-9]") print(result) # [1] "W919 Z846"
另外补充个小细节:你的正则里{1}是多余的,可以直接写成Z84[1-9],效果完全一样哦!
这样应该就能得到你想要的结果了,有问题随时问~




