如何在R/Python中用正则从截断信息生成多列data.frame
解决R中单列data.frame拆分三列的问题
原始数据的结构是交替的票据编号行与机构+金额行(存在一组无机构仅含金额的情况),直接逐行提取会导致字段错位,需先分组配对再处理。以下是完整的解决方案:
完整代码
library(dplyr) library(tidyr) library(stringr) # 给数据添加分组标识,每2行分为一组 dados_df <- dados_df %>% mutate(group_id = ceiling(row_number() / 2)) # 将每组的两行合并为完整文本,方便后续提取 dados_combined <- dados_df %>% pivot_wider(names_from = group_id, values_from = V1) %>% pivot_longer(cols = everything(), names_to = "group_id", values_to = "combined") %>% drop_na(combined) %>% group_by(group_id) %>% summarise(full_text = str_c(combined, collapse = " ")) %>% ungroup() # 提取字段并处理金额格式 result <- dados_combined %>% mutate( # 提取票据编号nota nota = str_extract(full_text, "^N\\s\\d+NE\\d+\\s\\d+"), # 提取机构名称org,去除前后空格;无机构时返回空 org = str_trim(str_extract(full_text, "(?<=^N\\s\\d+NE\\d+\\s\\d+\\s).*(?=\\s{2,}\\d+[.,]?\\d*,\\d{2}\\sC$)")), # 提取金额并转换格式:将欧洲式金额转为标准小数格式 value_raw = str_extract(full_text, "\\d+[.,]?\\d*,\\d{2}\\sC$"), value = ifelse(is.na(value_raw), NA, str_c(format(as.numeric(str_replace_all(value_raw, c("\\.", "", ",\\sC$" = "")), decimal.mark = ","), big.mark = "", decimal.mark = ".", nsmall = 2), " C")) ) %>% select(nota, org, value) # 输出结果 print(result, width = Inf)
关键步骤说明
- 分组合并:通过
ceiling(row_number()/2)生成分组ID,将每两行的票据信息与对应详情合并为完整文本,解决逐行提取的错位问题。 - nota提取:用正则
^N\\s\\d+NE\\d+\\s\\d+精准匹配开头的票据编号,确保只提取有效内容。 - org提取:利用正向断言定位票据编号与金额之间的文本,用
str_trim清理多余空格,无机构的分组会自动返回空值。 - 金额格式转换:处理欧洲式金额格式(如
7.500,00),替换千分位符号、转换小数分隔符,最终格式化为X.XX C的标准形式。
运行结果
# A tibble: 7 × 3 nota org value <chr> <chr> <chr> 1 N 2022NE001264 75 FRETES INTERNACIONAIS LTDA 7500.00 C 2 N 2022NE000286 84 UNIRIO UNIVERSIDADE FEDERAL DO ESTADO RJ 2856.71 C 3 N 2022NE001297 48 "" 720.00 C 4 N 2022NE001333 16 CASTRO COMERCIO LTDA 5256.00 C 5 N 2022NE001353 92 CONSTRUCOES E INSTALACOES LTDA 734.20 C 6 N 2022NE000279 12 UNIRIO UNIVERSIDADE FEDERAL DO ESTADO RJ 180.00 C 7 N 2022NE000293 12 EQUIPAMENTOS E PRODUTOS PARA LABORATORIOS L 1716.00 C
内容的提问来源于stack exchange,提问作者DATAUNIRIO
相关产品推荐
相关产品推荐

