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

R语言grep匹配长短横杠分隔的位置字符串返回NA问题求解

问题描述

我有一个名为df_parse的dataframe,结构如下:

error             error_position
1       0                           
2       0                           
3       0                           
4       1                    24 - 26
5       1                    29 - 30
6       0                           
7       0                           
8       0                           
9       0                           
10      0                           
11      0                           
12      0                           
13      0                           
14      0                           
15      0                           
16      0                           
17      0                           
18      0                           
19      0                           
20      0                           
21      0                           
22      0                           
23      1                    78 - 78
24      0                           
25      1                    83 - 84
26      0                           
27      0                           
28      0                           
29      1                    92 - 92
30      1                    95 - 95
31      0                           
32      0                           
33      0                           
34      0                           
35      0                           
36      0                           
37      1                  111 - 113

我需要在字符向量格式的原始数据raw中,查找error_position列中的字符串对应的位置,原始数据样例如下:

HUBUSL1 2   ENTER LINE NUMBER   81 - 82
    FOR HUBUS = 1 VALID ENTRIES
    
    
    83 - 84
    
    VALID ENTRIES
    
    1   MIN VALUE
    99  MAX VALUE
    
    HUBUSL3 2   See BUSL1   85 - 86
    
    VALID ENTRIES
    
    1   MIN VALUE
    99  MAX VALUE
    
    HUBUSL4 2   See BUSL1   87 - 88
    
    VALID ENTRIES
    
    1   MIN VALUE
    99  MAX VALUE
     
    
    
    A2. GEOGRAPHIC INFORMATION
    GEREG   2   REGION  89 - 90
    
    EDITED UNIVERSE:    ALL HHLD's IN SAMPLE VALID ENTRIES
    1   NORTHEAST
    2   MIDWEST (FORMERLY NORTH CENTRAL)
    3   SOUTH
    4   WEST
    
    GEDIV   1   DIVISION    91 - 91
    
    EDITED UNIVERSE:    ALL HHLD's IN SAMPLE VALID ENTRIES








92 – 92


GESTFIPS    2   FEDERAL INFORMATION 93 - 94
PROCESSING STANDARDS (FIPS) STATE CODE

例如df_parse的error_position列第25行的"83 - 84"匹配原始文件第5行,"92 – 92"匹配样例原始数据末尾的对应行。

我编写了如下for循环,使用grep从raw向量中返回error_position值的匹配位置:

results1<- vector(mode = "character", length = length(df_parse$error)) #empty vector

for(i in seq_along(df_parse$error)){
    results1[i]<- ifelse(df_parse$error[i] == 1, grep(pattern = paste(df_parse$error_position[i]), x = raw, value = FALSE), "")
    
}

results1 

返回的样例结果如下:

[1] ""     ""     ""     "37"   "95"   ""     ""     ""     ""     ""     ""     ""     ""     ""    
 [15] ""     ""     ""     ""     ""     ""     ""     ""     "288"  ""     "298"  ""     ""     ""    
 [29] NA     "381"  ""     ""     ""     ""     ""     ""     "444"  ""     ""     ""     ""     ""    
 [43] ""     "532"  ""     "551"  ""     ""     ""     ""     NA     ""     ""     "677"  ""     ""    
 [57] "712"  ""     ""     ""     ""     ""     ""     ""     "838"  ""     ""     ""     ""     ""    
 [71] ""     ""     NA     ""     ""     ""     ""     "991"  ""     ""     ""     ""     ""     ""    
 [85] ""     ""     NA     "1140" ""     "1158" ""     ""     ""     ""     ""     ""     ""     ""    
 [99] ""     ""     ""     ""     ""     "1283" ""     ""     ""     NA     ""     ""     ""     ""    
[113] ""     ""     ""     ""     ""     ""     ""     ""     ""     ""     ""     ""     ""     "1658"
[127] ""     ""     ""     NA     ""     ""     "1749" ""     ""     ""     ""     ""     ""     ""    
[141] "1824" ""     ""     ""     ""     ""     ""     ""     ""     ""     ""     ""     ""     ""    
[155] ""     ""     "2065" ""     ""     "2109" ""     ""     ""     ""     ""     "2161" ""     ""    
[169] ""     NA     ""     ""     ""     ""     ""     ""     ""     ""     "2344" ""     ""     ""    

这个结果基本符合预期,但我发现其中存在多处NA。排查后发现NA的产生原因是部分数字范围的分隔符不是普通短横杠,而是em长横杠:比如原始数据中的"92 – 92"是长横杠,而df_parse的error_position中存储的是普通短横杠格式的"92 - 92"。

但我尝试直接使用grep匹配长横杠格式的"92 – 92"时,仍然返回integer(0)无匹配结果,尝试过的写法如下:

grep(pattern = "92 – 92", x = raw, value = FALSE)  == integer(0)
grep(pattern = paste(df_parse$error_position[29]), x = raw, value = FALSE) == integer(0)
解决方案

方案1:统一预处理数据源格式后匹配

先把原始向量和匹配字段的横杠、空格做标准化处理,消除格式差异:

library(stringr)
# 预处理raw:替换所有长横杠为短横杠,同时压缩多余空格
raw_clean <- str_squish(gsub("–", "-", raw, fixed = TRUE))

results1 <- vector(mode = "character", length = length(df_parse$error)) 
for(i in seq_along(df_parse$error)){
  if(df_parse$error[i] == 1){
    # 预处理匹配字段:同样压缩多余空格
    pattern <- str_squish(df_parse$error_position[i])
    match_res <- grep(pattern, raw_clean, fixed = TRUE, value = FALSE)
    # 处理无匹配的情况,避免返回integer(0)导致NA
    results1[i] <- ifelse(length(match_res) > 0, as.character(match_res[1]), "")
  } else {
    results1[i] <- ""
  }
}

方案2:用正则兼容任意横杠格式

不需要修改原始数据,构造匹配模式时兼容长短横杠和任意空格:

results1 <- vector(mode = "character", length = length(df_parse$error)) 
for(i in seq_along(df_parse$error)){
  if(df_parse$error[i] == 1){
    # 把pattern里的短横杠替换为兼容长短横杠、任意前后空格的正则
    pattern <- gsub("-", "\\s*[–-]\\s*", df_parse$error_position[i], fixed = TRUE)
    match_res <- grep(pattern, raw, value = FALSE)
    results1[i] <- ifelse(length(match_res) > 0, as.character(match_res[1]), "")
  } else {
    results1[i] <- ""
  }
}

额外排查点

如果修改后仍有匹配失败,可通过stringi::stri_escape_unicode()分别打印匹配字段和raw对应行的编码,检查是否存在其他不可见特殊字符。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 12:09:03