You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R data.table中正则提取指定捕获组结果异常的解决方案

问题原因

你之前的写法错误核心是:stri_match_all返回的是和输入向量等长的列表,每个列表元素对应一个输入字符串的匹配矩阵。直接对整个列表调用unlist()会把所有匹配结果拍平成一个一维长向量,此时取[3]只是取了这个长向量的第3个值,再自动循环填充到所有行,自然会出现所有行都返回第一行结果的问题。

另外你用的临时方案多余了:stri_match_first本身返回的就是行与输入完全对齐的矩阵,不需要先把整个矩阵存为列再二次取子集,直接索引矩阵列就能拿到对应捕获组的全部结果。

最简实现方法

首先统一存一下正则表达式(注意下划线_不是正则特殊字符,不需要加反斜杠转义,R字符串里的正则转义符要写双反斜杠):

library(data.table)
library(stringi)

dt.test <- data.table(file_names = c("20200131_20210228_PROD_TEST_MF_delta_20210228_20210107_20210210.csv"
                                   , "20200531_20210531_PROD_TEST_MF_delta_20210531_20210523_20210608.csv" ))
pattern <- "(?i)(\\d*)_(\\d*)_([A-Z]*_[A-Z]*_[A-Z]*_[A-Z]*)_(\\d*)_(\\d*)_(\\d*)"

你预期输出里的20210228/20210531对应正则的第5个捕获组(匹配结果矩阵第1列是完整匹配内容,捕获组从第2列开始计数),直接取矩阵对应列即可:

dt.test[, Extract.1 := stri_match_first(file_names, regex = pattern)[, 5]][]

运行后输出完全符合预期:

file_names Extract.1
1: 20200131_20210228_PROD_TEST_MF_delta_20210228_20210107_20210210.csv  20210228
2: 20200531_20210531_PROD_TEST_MF_delta_20210531_20210523_20210608.csv  20210531

要取其他捕获组只要改列号就行,比如取第一个起始日期就把列号改成2,取产品标识段就改列号为4。

多匹配场景适配

如果你的文本存在一个字符串对应多个匹配结果的情况(必须用stri_match_all),可以用vapply按行遍历列表提取对应捕获组,避免unlist拍平的问题:

dt.test[, Extract.1 := vapply(
  stri_match_all(file_names, regex = pattern),
  FUN = \(match_mat) match_mat[1, 5], # 取每个字符串第一个匹配的第5个捕获组
  FUN.VALUE = character(1)
)][]
可选简化方案

如果你只需要提取固定位置的特定内容,甚至不需要写全量正则配捕获组,直接用零宽断言匹配目标片段即可,不用数捕获组序号:

# 直接提取PROD_TEST_MF_delta_后面紧跟的8位日期
dt.test[, Extract.1 := stri_extract_first_regex(file_names, "(?i)(?<=PROD_TEST_MF_delta_)\\d{8}")]

内容的提问来源于stack exchange,提问作者hannes101

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 14:36:14