在R中使用str_match_all无法提取特定子串到新变量的问题
问题解决:从审核历史字符串中提取状态及相关信息
核心问题分析
- 正则表达式逻辑错误:你使用的
(?<= From).+(?>=\\s)既没有精准定位From后带引号的状态文本,还存在正向预查语法错误(多了额外的=符号) - 代码变量混乱:存在变量名不匹配(定义
from却用source赋值)、初始对象未正确初始化、匹配link/date的正则与原字符串格式不符(原字符串无Link:/Date:标识)等问题
修正方案
1. 精准匹配的正则表达式
针对提取From后的状态,使用专门匹配引号内文本的正则:
# 仅提取From后的状态 str_match_all(col1, 'From "([^"]+)"')[[1]][, 2]
正则解释:
From ":匹配固定前缀([^"]+):捕获引号内所有非引号字符(即目标状态文本)":匹配闭合引号
如果要一次性提取From/To状态、日期、负责用户,可使用更完整的正则:
pattern <- 'From "([^"]+)" --> "([^"]+)" on ([0-9/]+) - ([0-9:]+) by ([^ ]+)' matches <- str_match_all(col1, pattern)[[1]]
该正则会捕获以下内容:
- 第2列:
from状态 - 第3列:
to状态 - 第4列:日期
- 第5列:时间
- 第6列:负责用户
2. 重构代码(用tidyverse实现高效向量式操作)
替换原循环代码,避免循环常见错误:
library(tidyverse) # 读取并预处理原始数据 newERM2019Over <- read.csv("ERM Events2019over.csv", fileEncoding = "latin1") newERM2019Over <- newERM2019Over %>% mutate(NodeID = Node.ID) # 修正原代码的变量名拼写错误 # 提取审核历史的所有字段 mod_history_df <- newERM2019Over %>% mutate( # 匹配每条审核记录的所有字段 mod_matches = map(Moderation.history, ~str_match_all(.x, 'From "([^"]+)" --> "([^"]+)" on ([0-9/]+) - ([0-9:]+) by ([^ ]+)')[[1]]), # 将匹配结果转为结构化数据框 mod_data = map(mod_matches, ~as.data.frame(.x, stringsAsFactors = FALSE) %>% select(from = V2, to = V3, date = V4, user_responsible = V6)) ) %>% unnest(mod_data) %>% select(NodeID, from, to, date, user_responsible) # 合并原始数据与提取的审核历史 newERM2019Over_Mod_History <- left_join(newERM2019Over, mod_history_df, by = "NodeID")
3. 原循环代码的关键修正(若坚持使用循环)
- 初始化
df对象,避免rbind时报错 - 统一变量名:将
source替换为from - 修正日期、用户的提取正则(原字符串无
Link:/Date:标识):
date <- str_match_all(col1, '(?<=on )[0-9/]+')[[1]][,1] user_responsible <- str_match_all(col1, '(?<=by )[^ ]+')[[1]][,1]
测试验证
用你提供的测试字符串验证提取效果:
test_str <- 'From "Submitted to QM" --> "Published" on 06/06/2019 - 09:16 by user@example.com From "Under revision request" --> "Submitted to QM" on 23/05/2019 - 11:42 by Andyprendergast From "Submitted to QM" --> "Under revision request" on 20/05/2019 - 15:10 by user@example.com From "Submitted to QM" --> "Submitted to QM" on 15/05/2019 - 17:14 by user@example.com From "Draft" --> "Submitted to QM" on 13/05/2019 - 10:13 by Andyprendergast' # 提取From后的状态 str_match_all(test_str, 'From "([^"]+)"')[[1]][,2] # 输出结果: # [1] "Submitted to QM" "Under revision request" "Submitted to QM" "Submitted to QM" "Draft"
内容的提问来源于stack exchange,提问作者Lucian
相关产品推荐
相关产品推荐

