【问题标题】:Inverse matching with stringr与 stringr 反向匹配
【发布时间】:2018-05-15 14:22:48
【问题描述】:

我想使用stringr 包删除所有与字符串模式不匹配的字符。到目前为止,我已经能够使用"\\w+(?= (grape|satsuma))" 作为模式删除模式之前的那些,但在模式仍然不可能之后删除那些。

> str_remove_all("apples grape banana melon olive persimon grape apples satsuma papaya", 
+                "\\w+(?= (grape|satsuma))")
[1] " grape banana melon olive  grape  satsuma papaya"

想要的结果是:

"grape grape satsuma"

注意:我知道在这种情况下最简单的方法是仅提取“葡萄”和“萨摩”,但出于分析目的,我更喜欢这种方式)

已编辑提供整个问题

整个问题如下,给定一个 d 数据框,其中包含一个带有字符串的列,该函数应仅在匹配时返回同一列:

> d
# A tibble: 2 x 2
  string_column                  c2
  <chr>                       <dbl>
1 apples grape banana satsuma     3
2 grape banana satsuma melon      4

使用@d.r 提供的答案有效:

> d %>% 
+   mutate_at(vars(string_column), ~ gsub("(grape|satsuma| )(*SKIP)(*FAIL)|.", "", ., perl = TRUE))

# A tibble: 2 x 2
  string_column        c2
  <chr>             <dbl>
1 " grape  satsuma"     3
2 "grape  satsuma "     4

到目前为止使用stringr 包提供的所有答案都无法返回string_column

这是dputd

d <- structure(list(string_column = c("apples grape banana satsuma", 
"grape banana satsuma melon"), c2 = c(3, 4)), row.names = c(NA, 
-2L), class = c("tbl_df", "tbl", "data.frame"))

【问题讨论】:

  • gsub("(grape|satsuma| )(*SKIP)(*FAIL)|.", "", "apples grape banana melon olive persimon grape apples satsuma papaya", perl = TRUE)
  • @d.b 是的!但我想使用stringr 包,有什么想法吗?
  • 使用str_remove_all"\\w+(?= (grape|satsuma))" 作为模式删除grapesatsuma 之前的单词。我的期望结果是str_remove_all 删除所有与papayasatsuma 不匹配的内容,因此在这种情况下的期望结果是:"grape grape satsuma"。请让我知道目的是否不够明确。

标签: r regex stringr


【解决方案1】:

您可能想查看链接线程中的negative lookaheads 和一些相关的正则表达式技术。

但是,由于我们要提取单词,我宁愿使用str_extract_all,我会这样做:

str_extract_all("apples grape banana melon olive persimon grape apples satsuma papaya", 
                               "grape|satsuma")
 "grape"   "grape"   "satsuma"

我也很喜欢@steveLangsford 在评论中留下的这句话:

paste0(unlist(str_extract_all("apples grape banana melon olive persimon grape apples satsuma papaya", "grape|satsuma")), collapse=" ") 
"grape grape satsuma"

根据我们的讨论/cmets 进一步了解:

string_column <- c("apples grape banana satsuma", "grape banana satsuma melon") 
c2            <- c(3, 4) 
d             <- tibble(string_column,c2) 

myfun <- function(x) {paste0(unlist(str_extract_all(x, "grape|satsuma")), collapse=" ") }

sapply(d$string_column, myfun)
        "grape satsuma"             "grape satsuma"

【讨论】:

  • 使用str_extract_all 解决了正则表达式的问题。但是我需要在数据框的列中应用它,所以我需要表达式只返回一个字符串。在尝试了str_extract_allstr_cmap_df 之后,我认为最简单的方法可能是尝试在正则表达式中使用逆匹配,但这似乎也是不可能的。我尝试了几个正则表达式 "\\w+(?= (grape|satsuma))" 最接近我的目的。
  • @TitoSanz 我明白了。让我在午饭时间多做一点,看看我能不能为此添加一些东西。
  • paste0(unlist(str_extract_all("apples 葡萄香蕉瓜橄榄柿葡萄苹果satsuma papaya", "grape|satsuma")), collapse="")
  • 让我们假设 @steveLangsford 的方法,当我尝试沿数据框中的列应用时,这会返回错误:
  • @TitoSanz 请粘贴错误也许它可以应用不同。您应用它的代码也很好。与此同时,我正在研究另一种方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-20
  • 1970-01-01
  • 1970-01-01
  • 2021-06-21
  • 1970-01-01
  • 2021-09-06
  • 2020-01-24
相关资源
最近更新 更多