如何使用 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"
嘿,我有一个数据集,我手工挑选了以下 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"