如何使用 stringr 和 regex 转换字符串(更改、保留、提取)但有一些例外?

How to use stringr and regex to convert strings(change, keep, extract) with some exceptions?

嘿,我有一个数据集,我手工挑选了以下 7 个条目作为示例:

mydf <- data.frame(transmission = c('Auto(L3)','Auto(L4)','Auto (S4)','Automatic (6-spd)','Automatic (L3)',
'Automatic (variable gear ratios)', 'Manual 4-spd'))

也就是

                      transmission
1                         Auto(L3)
2                         Auto(L4)
3                        Auto (S4)
4                  Automatic 6-spd
5                   Automatic (L3)
6 Automatic (variable gear ratios)
7                     Manual 4-spd

要求是将 Auto(...) 转换为 Automatic ... - 如 Auto(L3) 转换为 Automatic L3,Auto (S4) 转换为 Automatic S4 - 并删除“(”、“)”、 '-' 或 ' ' 除了手动或自动之后的第一个空白 space - 就像自动 (6-spd) 到自动 6spd。

结果应该是:

                      transmission
1                     Automatic L3
2                     Automatic L4
3                     Automatic S4
4                   Automatic 6spd
5                     Automatic L3
6     Automatic variablegearratios
7                      Manual 4spd

目前我使用的可能是最笨的方法:

transmission %>% 
  str_replace_all(' \(',' ') %>%
  str_replace_all('Auto ','Automatic ') %>%
  str_replace_all(' ','') %>%
  str_replace_all('[()-]','') %>%
  str_replace_all('Automatic','Automatic ') %>%
  str_replace_all('Manual','Manual ')

但这既多余又费时。 使用 stringr 包(str_xxx 函数)和正则表达式的正确和直接的方法是什么?

提前致谢。

> mydf
                      transmission
1                         Auto(L3)
2                         Auto(L4)
3                        Auto (S4)
4                Automatic (6-spd)
5                   Automatic (L3)
6 Automatic (variable gear ratios)
7                     Manual 4-spd

> mydf$transmission_r = str_replace(mydf$transmission, "Auto(?:matic)?\s?\((.*)\)", "Automatic \1")
> mydf$transmission_r = str_replace_all(mydf$transmission_r, "-", "")
> mydf$transmission_r = str_replace_all(mydf$transmission_r, "(?<!Automatic|Manual)\s", "")
> mydf
                      transmission                 transmission_r
1                         Auto(L3)                   Automatic L3
2                         Auto(L4)                   Automatic L4
3                        Auto (S4)                   Automatic S4
4                Automatic (6-spd)                 Automatic 6spd
5                   Automatic (L3)                   Automatic L3
6 Automatic (variable gear ratios)   Automatic variablegearratios
7                     Manual 4-spd                    Manual 4spd

说明

以单词 "Auto" 开头,然后使用非匹配组(使用 ?:),表示可能存在 "matic"(使用 (matic)?) .接下来,指示可能存在 space (\s?)。接下来,转义左括号 (\(),捕获匹配组中的所有文本 ((.*)),最后转义右括号 (\()。这是我们的正则表达式。然后,我们将其替换为单词 "Automatic",后跟在我们的第一个匹配组 (\1) 中捕获的任何内容,即括号内的任何内容。

删除连字符现在只是使用 str_replace_all 删除连字符,删除所有 space 除了 "Manual" 或 "Automatic" 之间的那些只是我们使用否定向后看以确保 space 前面没有这些词(使用 (?<!Automatic|Manual))。

正则表达式少一点,多一点strsplit:

mydf$transmission <- gsub("Auto(?=[^m])", "Automatic", mydf$transmission, perl=TRUE)
sapply(
  strsplit(gsub("[()-]", " ", mydf$transmission), "\s+"),
  function(x) paste(x[1], paste0(x[-1],collapse="") )
)
#[1] "Automatic L3"                 "Automatic L4"                
#[3] "Automatic S4"                 "Automatic 6spd"              
#[5] "Automatic L3"                 "Automatic variablegearratios"
#[7] "Manual 4spd"