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

R数据框中基于字符串格式适配正则提取字段的优化需求

解决R语言交易短信的字段精准提取问题

我明白你现在遇到的困扰:同一个数据框里的交易短信格式差异不小,前两条能用正则正常提取字段,但第三条因为结构特殊,好多信息都抽不出来。别担心,咱们可以先给每条短信做格式分类,再匹配对应的正则规则,就能精准提取出需要的六个字段了。

首先先看一下你的原始输入数据:

library(stringr)
input = structure(list( `Sr. No.`=c("1", "2","3"), String=c( 
"ABCD, your Account XX1987 has been credited with EUR 22,500.00 on 30-Oct-17. Info: CAM*CASH DEPOSIT*ELISH SEC. The Available Balance is EUR 22,951.57.", 
"WXYZ, Your Ac XXXXXXXX1987 is debited with USD 5,000.00 on 14 May. Info. MMT*125485645*99999999. Your Net Available Balance is USD 20,531.38.", 
"INR 187,314.00 credited to your A/c No XXXXXXX1234 on 31/10/17 through NEFT with UTR )")), .Names=c("Sr. No.", "String"), row.names=1:3, class="data.frame")

问题分析

第三条短信的结构和前两条完全不一样:

  • 交易金额和类型放在最开头,不是中间位置
  • 日期用/分隔,不是前两条的-或空格
  • 没有明确的Info标签,交易描述藏在through后面
  • 完全没提可用余额,所以这个字段应该返回NA

所以咱们的核心思路是:先识别每条短信的格式类型,再针对不同类型用对应的正则提取字段。

解决方案代码

library(stringr)
library(dplyr)

# 第一步:给每条短信标记格式类型
input <- input %>%
  mutate(
    format_type = case_when(
      # 格式1:包含Info标签和Balance相关内容(对应前两条)
      str_detect(String, "Info\\.|Info:") & str_detect(String, "Available Balance|Net Available Balance") ~ "type1",
      # 格式2:包含"credited to your A/c No",无Info和Balance(对应第三条)
      str_detect(String, "credited to your A/c No") ~ "type2",
      # 其他格式默认type0,这里暂时不用处理
      TRUE ~ "type0"
    )
  )

# 第二步:针对不同格式提取目标字段
result <- input %>%
  mutate(
    # 提取交易类型:去除末尾的ed
    Type = case_when(
      format_type == "type1" ~ str_extract(String, "(credit|debit)ed") %>% str_remove("ed"),
      format_type == "type2" ~ str_extract(String, "(credit)ed") %>% str_remove("ed")
    ),
    # 提取账号:取字符串末尾的数字部分
    Acc = case_when(
      format_type == "type1" ~ str_extract(String, "(?:Account|Ac|XX)[^0-9]*([0-9]+)") %>% str_extract("[0-9]+"),
      format_type == "type2" ~ str_extract(String, "A/c No XXXXXXX([0-9]+)") %>% str_remove("A/c No XXXXXXX")
    ),
    # 提取交易金额(含币种)
    Fig = case_when(
      format_type == "type1" ~ str_extract(String, "(?:EUR|USD|INR) [0-9,.]+"),
      format_type == "type2" ~ str_extract(String, "(?:INR) [0-9,.]+")
    ),
    # 提取交易日期:适配不同分隔符
    Data = case_when(
      format_type == "type1" ~ str_extract(String, "on ([0-9]+[ -](?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)|[0-9]+[ -][0-9]+)") %>% str_remove("on "),
      format_type == "type2" ~ str_extract(String, "on ([0-9]+/[0-9]+/[0-9]+)") %>% str_remove("on ")
    ),
    # 提取交易描述:适配不同标签
    Desc = case_when(
      format_type == "type1" ~ str_extract(String, "Info[:.] (.+)(?=\\. )"),
      format_type == "type2" ~ str_extract(String, "through (.+)") %>% str_remove("through ") %>% str_remove(" \\)$")
    ),
    # 提取可用余额:type2无相关内容,自动返回NA
    Balance = case_when(
      format_type == "type1" ~ str_extract(String, "(?:Available Balance|Net Available Balance) is ([A-Z]+ [0-9,.]+)") %>% str_remove("(?:Available Balance|Net Available Balance) is ")
    )
  ) %>%
  # 保留并重命名需要的字段
  select(Sr.No = `Sr. No.`, Type, Acc, Fig, Data, Desc, Balance)

# 查看最终结果
print(result)

代码关键点说明

  1. 格式分类:用case_when结合str_detect识别短信的特征,精准划分格式类型;
  2. 字段适配:每个字段都针对不同格式调用专属正则,比如日期部分同时适配-/空格和/两种分隔方式;
  3. NA自动处理:第三条短信没有可用余额,Balance字段会自动返回NA,完全符合预期。

最终输出结果

Sr.NoTypeAccFigDataDescBalance
1credit1987EUR 22,500.0030-Oct-17CAMCASH DEPOSITELISH SECEUR 22,951.57
2debit1987USD 5,000.0014 MayMMT12548564599999999USD 20,531.38
3credit1234INR 187,314.0031/10/17NEFT with UTRNA

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:56:26