【问题标题】:R: show matched special character in a stringR:在字符串中显示匹配的特殊字符
【发布时间】:2020-04-22 05:40:05
【问题描述】:

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

示例数据框:

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))

【问题讨论】:

    标签: r regex gsub


    【解决方案1】:

    如果我们只需要第一个特殊字符,您可以使用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)))
    

    【讨论】:

      【解决方案2】:

      我们可以在这里使用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!!"))
      

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

      编辑:

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

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

      【讨论】:

      • 我的原帖显示有排除的字符,你能根据这个编辑你的答案吗?
      • @Ibo 检查更新的答案。在grepl 逻辑中,我现在有一个否定的前瞻,它排除了你想要备用的几个符号。脚本的其余部分和输出实际上与此更改保持一致。
      • 如果有多个则只显示最后一个特殊字符
      • 您想查看所有字符吗?我现在会更新。此外,您接受的答案不排除您要保留的符号。
      【解决方案3】:

      使用(插入符号)而不是“^”运算符的基本 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 != ""
        }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-05-09
        • 2014-07-12
        • 2020-12-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-19
        • 1970-01-01
        相关资源
        最近更新 更多