R:显示字符串中匹配的特殊字符

R: show matched special character in a string

如何在单列数据框的每一行中显示匹配的特殊字符?

示例数据框:

a <- data.frame(name=c("foo","bar'","ip_sum","four","%23","2_planet!","@abc!!"))

判断字符串是否有特殊字符:

a$name_cleansed <- gsub("([-./&,])|[[:punct:]]","\1",a$name) #\1 puts back the exception we define (dash and slash)

a <- a %>% mutate(has_special_char=if_else(name==name_cleansed,FALSE,TRUE))

如果我们只需要第一个特殊字符,您可以使用str_extract

library(stringr)
str_extract(a$name,'[[:punct:]]')
#[1] NA  "'" "_" NA  "%" "_" "@"

如果我们需要所有特殊字符,我们可以使用 str_extract_all

sapply(str_extract_all(a$name,'[[:punct:]]'), function(x) toString(unique(x)))
#[1] ""     "'"    "_"    ""     "%"    "_, !" "@, !"

要排除某些符号,我们可以使用

exclude_symbol <- c('-', '.', '/', '&', ',')

sapply(str_extract_all(a$name,'[[:punct:]]'), function(x) 
                       toString(setdiff(unique(x), exclude_symbol)))

我们可以在这里使用 grepl 作为基础 R 选项:

a$has_special_char <- grepl("(?![-./&,])[[:punct:]]", a$name, perl=TRUE)
a$special_char <- ifelse(a$has_special_char, sub("^.*([[:punct:]]).*$", "\1", a$name), NA)
a

       name has_special_char special_char
1       foo            FALSE         <NA>
2      bar'             TRUE            '
3    ip_sum             TRUE            _
4      four            FALSE         <NA>
5       %23             TRUE            %
6 2_planet!             TRUE            !
7    @abc!!             TRUE            !

数据:

a <- data.frame(name=c("foo","bar'","ip_sum","four","%23","2_planet!","@abc!!"))

以上逻辑returns,任意,第一个符号字符,如果存在,在每个名称中,否则返回NA。它重复使用 has_special_char 列来确定名称中是否已经出现符号。

编辑:

如果你想要一个显示所有个特殊字符的列,那么使用:

a$all_special_char <- ifelse(a$has_special_char, gsub("[^[:punct:]]+", "", a$name), NA)

使用(脱字符号)而非“^”运算符的 Base R 正则表达式解决方案:

gsub("(^[-./&,])|[^[:punct:]]", "", a$name)

此外,如果您想要 data.frame 返回:

within(a, {
  special_char <- gsub("(^[-./&,])|[^[:punct:]]", "", name); 
  has_special_char <- special_char != ""})

如果您只想要每个名字的唯一特殊字符,如@Ronak Shah 的回答:

within(a, {
    special_char <- sapply(gsub("(^[-./&,])|[^[:punct:]]", "", a$name),
                           function(x){toString(unique(unlist(strsplit(x, ""))))});
    has_special_char <- special_char != ""
  }