R语言正则提取重复匹配大括号内文本并拆分至对应列的实现问题
原代码问题点
- 正则
[major]是字符组写法,仅会匹配m、a、j、o、r五个单字符,无法精准匹配完整关键词major - 正则中使用
.*贪婪匹配规则,遇到同一行多个同关键词的场景时,会跨标签匹配内容,无法拆分多个独立的大括号块 - 未兼容关键词和左大括号之间存在空格的场景(如测试数据第二行
major {andesite flows}的空格格式) - 匹配大括号内容的规则
(\\D[a-z]*)不支持带空格的文本(如andesite flows包含空格,无法被完整匹配) - 仅编写了major字段的提取逻辑,未覆盖minor、incidental两个字段的统一处理
可直接运行的正确实现
核心采用正向零宽断言编写正则:(?<=<关键词>\\s*\\{)[^}]+,规则为匹配前面紧邻「指定关键词+任意数量空格+左大括号」的所有非右大括号字符,既可以兼容关键词和大括号间的空格,也不会出现贪婪跨段匹配的问题,还能完整提取大括号内带空格的文本。
library(tidyverse) # 测试数据集 test <- data.frame(lith=c("major{basalt} minor{andesite} incidental{dacite rhyolite}", "major {andesite flows} major {dacite flows}", "major{andesite} minor{dacite}", "major{basaltic andesitebasalt}")) # 批量提取三类属性值 target_cols <- c("major", "minor", "incidental") test_result <- test %>% mutate(across(all_of(target_cols), function(.x){ # 动态拼接当前列对应的匹配正则 match_pattern <- str_c("(?<=", cur_column(), "\\s*\\{)[^}]+") # 提取所有匹配内容,用逗号合并,无匹配内容返回NA map_chr(str_extract_all(lith, match_pattern), ~if(length(.x) == 0) NA_character_ else str_flatten(.x, collapse = ", ")) }))
运行结果
执行代码后得到的输出如下,其中原预期输出存在笔误:第三行major对应内容为andesite,basaltic andesitebasalt实际是第四行major的取值。
| major | minor | incidental |
|---|---|---|
| basalt | andesite | dacite rhyolite |
| andesite flows, dacite flows | NA | NA |
| andesite | dacite | NA |
| basaltic andesitebasalt | NA | NA |
内容的提问来源于stack exchange,提问作者Wasatch801
相关产品推荐
相关产品推荐

